<commit_before>import {
  GraphQLInt,
  GraphQLFloat,
  GraphQLBoolean,
  GraphQLList,
  GraphQLInputObjectType,
  GraphQLNonNull,
  GraphQLString,
  GraphQLScalarType,
  GraphQLError,
} from 'graphql';

import GraphQLJSON from 'graphql-type-json';
import { Kind } from 'graphql/language';
import { IsoDateString, DateString } from './types';

const EmailType = new GraphQLScalarType({
  name: 'Email',
  serialize: value => {
    return value;
  },
  parseValue: value => {
    return value;
  },
  parseLiteral: ast => {
    if (ast.kind !== Kind.STRING) {
      throw new GraphQLError(`Query error: Can only parse strings got a: ${ast.kind}`);
    }

    // Regex taken from: http://stackoverflow.com/a/46181/761555
    const re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
    if (!re.test(ast.value)) {
      throw new GraphQLError(`Query error: Not a valid Email ${[ast]}`);
    }

    return ast.value;
  },
});

export const PaymentMethodInputType = new GraphQLInputObjectType({
  name: 'PaymentMethodInputType',
  description: 'Input type for PaymentMethod (paypal/stripe)',
  fields: () => ({
    id: { type: GraphQLInt },
    uuid: { type: GraphQLString }, // used to fetch an existing payment method
    token: { type: GraphQLString },
    service: { type: GraphQLString },
    type: {
      type: GraphQLString,
      description: 'creditcard, bitcoin, prepaid, manual',
    },
    customerId: { type: GraphQLString },
    data: { type: GraphQLJSON },
    name: { type: GraphQLString },
    primary: { type: GraphQLBoolean },
    monthlyLimitPerMember: { type: GraphQLInt },
    currency: { type: GraphQLString },
    save: { type: GraphQLBoolean },
  }),
});

export const PaymentMethodDataVirtualCardInputType = new GraphQLInputObjectType({
  name: 'PaymentMethodDataVirtualCardInputType',
  description: 'Input for virtual card (meta)data',
  fields: () => ({
    email: { type: GraphQLString, description: 'The email virtual card is generated for' },
  }),
});

export const StripeCreditCardDataInputType = new GraphQLInputObjectType({
  name: 'StripeCreditCardDataInputType',
  description: 'Input for stripe credit card data',
  fields: () => ({
    fullName: { type: GraphQLString },
    expMonth: { type: GraphQLInt },
    expYear: { type: GraphQLInt },
    brand: { type: GraphQLString },
    country: { type: GraphQLString },
    funding: { type: GraphQLString },
    zip: { type: GraphQLString },
  }),
});

export const UserInputType = new GraphQLInputObjectType({
  name: 'UserInputType',
  description: 'Input type for UserType',
  fields: () => ({
    id: { type: GraphQLInt },
    email: { type: EmailType },
    firstName: { type: GraphQLString },
    lastName: { type: GraphQLString },
    name: { type: GraphQLString },
    company: { type: GraphQLString },
    image: { type: GraphQLString },
    username: { type: GraphQLString },
    description: { type: GraphQLString },
    twitterHandle: { type: GraphQLString },
    githubHandle: { type: GraphQLString },
    website: { type: GraphQLString },
    paypalEmail: { type: GraphQLString },
    newsletterOptIn: { type: GraphQLBoolean },
  }),
});

export const MemberInputType = new GraphQLInputObjectType({
  name: 'MemberInputType',
  description: 'Input type for MemberType',
  fields: () => ({
    id: { type: GraphQLInt },
    member: { type: CollectiveAttributesInputType },
    collective: { type: CollectiveAttributesInputType },
    role: { type: GraphQLString },
    description: { type: GraphQLString },
    since: { type: DateString },
  }),
});

export const NotificationInputType = new GraphQLInputObjectType({
  name: 'NotificationInputType',
  description: 'Input type for NotificationType',
  fields: () => ({
    id: { type: GraphQLInt },
    channel: { type: GraphQLString },
    type: { type: GraphQLString },
    active: { type: GraphQLBoolean },
    webhookUrl: { type: GraphQLString },
    UserId: { type: GraphQLInt },
    CollectiveId: { type: GraphQLInt },
  }),
});

export const CollectiveInputType = new GraphQLInputObjectType({
  name: 'CollectiveInputType',
  description: 'Input type for CollectiveType',
  fields: () => ({
    id: { type: GraphQLInt },
    slug: { type: GraphQLString },
    type: { type: GraphQLString },
    name: { type: GraphQLString },
    company: { type: GraphQLString },
    website: { type: GraphQLString },
    twitterHandle: { type: GraphQLString },
    githubHandle: { type: GraphQLString },
    description: { type: GraphQLString },
    longDescription: { type: GraphQLString },
    expensePolicy: { type: GraphQLString },
    location: { type: LocationInputType },
    countryISO: {
      type: GraphQLString,
      deprecationReason: 'From 03/20/2019 - use `location.country` instead',
    },
    startsAt: { type: GraphQLString },
    endsAt: { type: GraphQLString },
    timezone: { type: GraphQLString },
    maxAmount: { type: GraphQLInt },
    currency: { type: GraphQLString },
    image: { type: GraphQLString },
    backgroundImage: { type: GraphQLString },
    tags: { type: new GraphQLList(GraphQLString) },
    tiers: { type: new GraphQLList(TierInputType) },
    settings: { type: GraphQLJSON },
    data: { type: GraphQLJSON },
    members: { type: new GraphQLList(MemberInputType) },
    notifications: { type: new GraphQLList(NotificationInputType) },
    paymentMethods: { type: new GraphQLList(PaymentMethodInputType) },
    HostCollectiveId: { type: GraphQLInt },
    hostFeePercent: { type: GraphQLInt },
    ParentCollectiveId: { type: GraphQLInt },
    // not very logical to have this here. Might need some refactoring. Used to add/edit members and to create a new user on a new order
    email: { type: GraphQLString },
    firstName: { type: GraphQLString },
    lastName: { type: GraphQLString },
  }),
});

export const ConnectedAccountInputType = new GraphQLInputObjectType({
  name: 'ConnectedAccountInputType',
  description: 'Input type for ConnectedAccountInputType',
  fields: () => ({
    id: { type: GraphQLInt },
    settings: { type: GraphQLJSON },
  }),
});

export const CollectiveAttributesInputType = new GraphQLInputObjectType({
  name: 'CollectiveAttributesInputType',
  description: 'Input type for attributes of CollectiveInputType',
  fields: () => ({
    id: { type: GraphQLInt },
    slug: { type: GraphQLString },
    type: { type: GraphQLString },
    name: { type: GraphQLString },
    company: { type: GraphQLString },
    firstName: { type: GraphQLString }, // for Collective type USER
    lastName: { type: GraphQLString }, // for Collective type USER
    email: { type: GraphQLString }, // for Collective type USER
    description: { type: GraphQLString },
    longDescription: { type: GraphQLString },
    expensePolicy: { type: GraphQLString },
    website: { type: GraphQLString },
    twitterHandle: { type: GraphQLString },
    githubHandle: { type: GraphQLString },
    location: { type: LocationInputType },
    countryISO: {
      type: GraphQLString,
      deprecationReason: 'From 03/20/2019 - use `location.country` instead',
    },
    startsAt: { type: GraphQLString },
    endsAt: { type: GraphQLString },
    timezone: { type: GraphQLString },
    maxAmount: { type: GraphQLInt },
    currency: { type: GraphQLString },
    settings: { type: GraphQLJSON },
    tags: { type: new GraphQLList(GraphQLString) },
  }),
});

export const LocationInputType = new GraphQLInputObjectType({
  name: 'LocationInputType',
  description: 'Input type for Location',
  fields: () => ({
    name: {
      type: GraphQLString,
      description: 'A short name for the location (eg. Google Headquarters)',
    },
    address: {
      type: GraphQLString,
      description: 'Postal address without country (eg. 12 opensource avenue, 7500 Paris)',
    },
    country: {
      type: GraphQLString,
      description: 'Two letters country code (eg. FR, BE...etc)',
    },
    lat: {
      type: GraphQLFloat,
      description: 'Latitude',
    },
    long: {
      type: GraphQLFloat,
      description: 'Longitude',
    },
  }),
});

export const TierInputType = new GraphQLInputObjectType({
  name: 'TierInputType',
  description: 'Input type for TierType',
  fields: () => ({
    id: { type: GraphQLInt },
    type: { type: GraphQLString },
    name: { type: GraphQLString },
    description: { type: GraphQLString },
    longDescription: {
      type: GraphQLString,
      description: 'A long, html-formatted description.',
    },
    videoUrl: {
      type: GraphQLString,
      description: 'Link to a video (YouTube, Vimeo).',
    },
    amount: {
      type: GraphQLInt,
      description: 'amount in the lowest unit of the currency of the host (ie. in cents)',
    },
    currency: { type: GraphQLString },
    presets: { type: new GraphQLList(GraphQLInt) },
    interval: { type: GraphQLString },
    maxQuantity: { type: GraphQLInt },
    minimumAmount: { type: GraphQLInt },
    amountType: { type: GraphQLString },
    maxQuantityPerUser: { type: GraphQLInt },
    goal: {
      type: GraphQLInt,
      description: 'amount that you are trying to raise with this tier',
    },
    password: { type: GraphQLString },
    settings: { type: GraphQLJSON },
    startsAt: {
      type: GraphQLString,
      description: 'Start of the campaign',
    },
    endsAt: {
      type: GraphQLString,
      description: 'End of the campaign',
    },
  }),
});

export const OrderInputType = new GraphQLInputObjectType({
  name: 'OrderInputType',
  description: 'Input type for OrderType',
  fields: () => ({
    id: { type: GraphQLInt },
    quantity: {
      type: GraphQLInt,
      defaultValue: 1,
    },
    totalAmount: { type: GraphQLInt },
    hostFeePercent: { type: GraphQLInt },
    platformFeePercent: { type: GraphQLInt },
    currency: { type: GraphQLString },
    interval: { type: GraphQLString },
    description: { type: GraphQLString },
    publicMessage: { type: GraphQLString },
    privateMessage: { type: GraphQLString },
    paymentMethod: { type: PaymentMethodInputType },
    matchingFund: {
      type: GraphQLString,
      description: 'The first part of the UUID of the PaymentMethod that can be used to match the donation',
    },
    referral: {
      type: CollectiveAttributesInputType,
      description: 'The referral collective',
    },
    user: { type: UserInputType },
    fromCollective: { type: CollectiveAttributesInputType },
    collective: { type: new GraphQLNonNull(CollectiveAttributesInputType) },
    tier: { type: TierInputType },
    customFields: { type: GraphQLJSON },
    recaptchaToken: { type: GraphQLString },
    // For taxes
    taxAmount: {
      type: GraphQLInt,
      description: 'The amount of taxes that were included in totalAmount',
      defaultValue: 0,
    },
    countryISO: {
      type: GraphQLString,
      description: 'User country, to know which tax applies',
    },
    taxIDNumber: {
      type: GraphQLString,
      description: 'User tax ID number',
    },
  }),
});

export const CommentInputType = new GraphQLInputObjectType({
  name: 'CommentInputType',
  description: 'Input type for CommentType',
  fields: () => ({
    id: { type: GraphQLInt },
    markdown: { type: GraphQLString },
    html: { type: GraphQLString },
    FromCollectiveId: { type: new GraphQLNonNull(GraphQLInt) },
    CollectiveId: { type: new GraphQLNonNull(GraphQLInt) },
    ExpenseId: { type: GraphQLInt },
    UpdateId: { type: GraphQLInt },
  }),
});

export const CommentAttributesInputType = new GraphQLInputObjectType({
  name: 'CommentAttributesInputType',
  description: 'Input type for CommentType',
  fields: () => ({
    id: { type: GraphQLInt },
    markdown: { type: GraphQLString },
    html: { type: GraphQLString },
    FromCollectiveId: { type: GraphQLInt },
    CollectiveId: { type: GraphQLInt },
    ExpenseId: { type: GraphQLInt },
    UpdateId: { type: GraphQLInt },
  }),
});

export const UpdateInputType = new GraphQLInputObjectType({
  name: 'UpdateInputType',
  description: 'Input type for UpdateType',
  fields: () => ({
    id: { type: GraphQLInt },
    views: { type: GraphQLInt },
    slug: { type: GraphQLString },
    title: { type: GraphQLString },
    image: { type: GraphQLString },
    isPrivate: { type: GraphQLBoolean },
    markdown: { type: GraphQLString },
    html: { type: GraphQLString },
    fromCollective: { type: CollectiveAttributesInputType },
    collective: { type: new GraphQLNonNull(CollectiveAttributesInputType) },
    tier: { type: TierInputType },
  }),
});

export const UpdateAttributesInputType = new GraphQLInputObjectType({
  name: 'UpdateAttributesInputType',
  description: 'Input type for UpdateType',
  fields: () => ({
    id: { type: GraphQLInt },
    views: { type: GraphQLInt },
    slug: { type: GraphQLString },
    title: { type: GraphQLString },
    image: { type: GraphQLString },
    isPrivate: { type: GraphQLBoolean },
    markdown: { type: GraphQLString },
    html: { type: GraphQLString },
    fromCollective: { type: CollectiveAttributesInputType },
    tier: { type: TierInputType },
  }),
});

export const ExpenseInputType = new GraphQLInputObjectType({
  name: 'ExpenseInputType',
  description: 'Input type for ExpenseType',
  fields: () => {
    return {
      id: { type: GraphQLInt },
      amount: { type: GraphQLInt },
      currency: { type: GraphQLString },
      createdAt: { type: DateString },
      incurredAt: { type: DateString },
      description: { type: GraphQLString },
      category: { type: GraphQLString },
      status: { type: GraphQLString },
      payoutMethod: {
        type: GraphQLString,
        description: 'Can be paypal, donation, manual, other',
      },
      privateMessage: { type: GraphQLString },
      attachment: { type: GraphQLString },
      user: { type: UserInputType },
      collective: { type: CollectiveAttributesInputType },
    };
  },
});

export const InvoiceInputType = new GraphQLInputObjectType({
  name: 'InvoiceInputType',
  description: 'Input dates and collectives for Invoice',
  fields: () => {
    return {
      dateFrom: { type: IsoDateString },
      dateTo: { type: IsoDateString },
      collectiveSlug: { type: GraphQLString },
      fromCollectiveSlug: { type: GraphQLString },
    };
  },
});
<commit_msg>feat(tier-customField): create a CustomFieldInputType<commit_after>import {
  GraphQLInt,
  GraphQLFloat,
  GraphQLBoolean,
  GraphQLList,
  GraphQLInputObjectType,
  GraphQLNonNull,
  GraphQLString,
  GraphQLScalarType,
  GraphQLError,
} from 'graphql';

import GraphQLJSON from 'graphql-type-json';
import { Kind } from 'graphql/language';
import { IsoDateString, DateString } from './types';

const EmailType = new GraphQLScalarType({
  name: 'Email',
  serialize: value => {
    return value;
  },
  parseValue: value => {
    return value;
  },
  parseLiteral: ast => {
    if (ast.kind !== Kind.STRING) {
      throw new GraphQLError(`Query error: Can only parse strings got a: ${ast.kind}`);
    }

    // Regex taken from: http://stackoverflow.com/a/46181/761555
    const re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
    if (!re.test(ast.value)) {
      throw new GraphQLError(`Query error: Not a valid Email ${[ast]}`);
    }

    return ast.value;
  },
});

export const PaymentMethodInputType = new GraphQLInputObjectType({
  name: 'PaymentMethodInputType',
  description: 'Input type for PaymentMethod (paypal/stripe)',
  fields: () => ({
    id: { type: GraphQLInt },
    uuid: { type: GraphQLString }, // used to fetch an existing payment method
    token: { type: GraphQLString },
    service: { type: GraphQLString },
    type: {
      type: GraphQLString,
      description: 'creditcard, bitcoin, prepaid, manual',
    },
    customerId: { type: GraphQLString },
    data: { type: GraphQLJSON },
    name: { type: GraphQLString },
    primary: { type: GraphQLBoolean },
    monthlyLimitPerMember: { type: GraphQLInt },
    currency: { type: GraphQLString },
    save: { type: GraphQLBoolean },
  }),
});

export const PaymentMethodDataVirtualCardInputType = new GraphQLInputObjectType({
  name: 'PaymentMethodDataVirtualCardInputType',
  description: 'Input for virtual card (meta)data',
  fields: () => ({
    email: { type: GraphQLString, description: 'The email virtual card is generated for' },
  }),
});

export const CustomFieldsInputType = new GraphQLInputObjectType({
  name: 'CustomFieldsInputType',
  description: 'Input for custom fields for order',
  fields: () => ({
    type: { type: GraphQLString },
    name: { type: GraphQLString },
    value: { type: GraphQLString },
    label: { type: GraphQLString },
    required: { type: GraphQLBoolean },
  }),
});

export const StripeCreditCardDataInputType = new GraphQLInputObjectType({
  name: 'StripeCreditCardDataInputType',
  description: 'Input for stripe credit card data',
  fields: () => ({
    fullName: { type: GraphQLString },
    expMonth: { type: GraphQLInt },
    expYear: { type: GraphQLInt },
    brand: { type: GraphQLString },
    country: { type: GraphQLString },
    funding: { type: GraphQLString },
    zip: { type: GraphQLString },
  }),
});

export const UserInputType = new GraphQLInputObjectType({
  name: 'UserInputType',
  description: 'Input type for UserType',
  fields: () => ({
    id: { type: GraphQLInt },
    email: { type: EmailType },
    firstName: { type: GraphQLString },
    lastName: { type: GraphQLString },
    name: { type: GraphQLString },
    company: { type: GraphQLString },
    image: { type: GraphQLString },
    username: { type: GraphQLString },
    description: { type: GraphQLString },
    twitterHandle: { type: GraphQLString },
    githubHandle: { type: GraphQLString },
    website: { type: GraphQLString },
    paypalEmail: { type: GraphQLString },
    newsletterOptIn: { type: GraphQLBoolean },
  }),
});

export const MemberInputType = new GraphQLInputObjectType({
  name: 'MemberInputType',
  description: 'Input type for MemberType',
  fields: () => ({
    id: { type: GraphQLInt },
    member: { type: CollectiveAttributesInputType },
    collective: { type: CollectiveAttributesInputType },
    role: { type: GraphQLString },
    description: { type: GraphQLString },
    since: { type: DateString },
  }),
});

export const NotificationInputType = new GraphQLInputObjectType({
  name: 'NotificationInputType',
  description: 'Input type for NotificationType',
  fields: () => ({
    id: { type: GraphQLInt },
    channel: { type: GraphQLString },
    type: { type: GraphQLString },
    active: { type: GraphQLBoolean },
    webhookUrl: { type: GraphQLString },
    UserId: { type: GraphQLInt },
    CollectiveId: { type: GraphQLInt },
  }),
});

export const CollectiveInputType = new GraphQLInputObjectType({
  name: 'CollectiveInputType',
  description: 'Input type for CollectiveType',
  fields: () => ({
    id: { type: GraphQLInt },
    slug: { type: GraphQLString },
    type: { type: GraphQLString },
    name: { type: GraphQLString },
    company: { type: GraphQLString },
    website: { type: GraphQLString },
    twitterHandle: { type: GraphQLString },
    githubHandle: { type: GraphQLString },
    description: { type: GraphQLString },
    longDescription: { type: GraphQLString },
    expensePolicy: { type: GraphQLString },
    location: { type: LocationInputType },
    countryISO: {
      type: GraphQLString,
      deprecationReason: 'From 03/20/2019 - use `location.country` instead',
    },
    startsAt: { type: GraphQLString },
    endsAt: { type: GraphQLString },
    timezone: { type: GraphQLString },
    maxAmount: { type: GraphQLInt },
    currency: { type: GraphQLString },
    image: { type: GraphQLString },
    backgroundImage: { type: GraphQLString },
    tags: { type: new GraphQLList(GraphQLString) },
    tiers: { type: new GraphQLList(TierInputType) },
    settings: { type: GraphQLJSON },
    data: { type: GraphQLJSON },
    members: { type: new GraphQLList(MemberInputType) },
    notifications: { type: new GraphQLList(NotificationInputType) },
    paymentMethods: { type: new GraphQLList(PaymentMethodInputType) },
    HostCollectiveId: { type: GraphQLInt },
    hostFeePercent: { type: GraphQLInt },
    ParentCollectiveId: { type: GraphQLInt },
    // not very logical to have this here. Might need some refactoring. Used to add/edit members and to create a new user on a new order
    email: { type: GraphQLString },
    firstName: { type: GraphQLString },
    lastName: { type: GraphQLString },
  }),
});

export const ConnectedAccountInputType = new GraphQLInputObjectType({
  name: 'ConnectedAccountInputType',
  description: 'Input type for ConnectedAccountInputType',
  fields: () => ({
    id: { type: GraphQLInt },
    settings: { type: GraphQLJSON },
  }),
});

export const CollectiveAttributesInputType = new GraphQLInputObjectType({
  name: 'CollectiveAttributesInputType',
  description: 'Input type for attributes of CollectiveInputType',
  fields: () => ({
    id: { type: GraphQLInt },
    slug: { type: GraphQLString },
    type: { type: GraphQLString },
    name: { type: GraphQLString },
    company: { type: GraphQLString },
    firstName: { type: GraphQLString }, // for Collective type USER
    lastName: { type: GraphQLString }, // for Collective type USER
    email: { type: GraphQLString }, // for Collective type USER
    description: { type: GraphQLString },
    longDescription: { type: GraphQLString },
    expensePolicy: { type: GraphQLString },
    website: { type: GraphQLString },
    twitterHandle: { type: GraphQLString },
    githubHandle: { type: GraphQLString },
    location: { type: LocationInputType },
    countryISO: {
      type: GraphQLString,
      deprecationReason: 'From 03/20/2019 - use `location.country` instead',
    },
    startsAt: { type: GraphQLString },
    endsAt: { type: GraphQLString },
    timezone: { type: GraphQLString },
    maxAmount: { type: GraphQLInt },
    currency: { type: GraphQLString },
    settings: { type: GraphQLJSON },
    tags: { type: new GraphQLList(GraphQLString) },
  }),
});

export const LocationInputType = new GraphQLInputObjectType({
  name: 'LocationInputType',
  description: 'Input type for Location',
  fields: () => ({
    name: {
      type: GraphQLString,
      description: 'A short name for the location (eg. Google Headquarters)',
    },
    address: {
      type: GraphQLString,
      description: 'Postal address without country (eg. 12 opensource avenue, 7500 Paris)',
    },
    country: {
      type: GraphQLString,
      description: 'Two letters country code (eg. FR, BE...etc)',
    },
    lat: {
      type: GraphQLFloat,
      description: 'Latitude',
    },
    long: {
      type: GraphQLFloat,
      description: 'Longitude',
    },
  }),
});

export const TierInputType = new GraphQLInputObjectType({
  name: 'TierInputType',
  description: 'Input type for TierType',
  fields: () => ({
    id: { type: GraphQLInt },
    type: { type: GraphQLString },
    name: { type: GraphQLString },
    description: { type: GraphQLString },
    longDescription: {
      type: GraphQLString,
      description: 'A long, html-formatted description.',
    },
    videoUrl: {
      type: GraphQLString,
      description: 'Link to a video (YouTube, Vimeo).',
    },
    amount: {
      type: GraphQLInt,
      description: 'amount in the lowest unit of the currency of the host (ie. in cents)',
    },
    currency: { type: GraphQLString },
    presets: { type: new GraphQLList(GraphQLInt) },
    interval: { type: GraphQLString },
    maxQuantity: { type: GraphQLInt },
    minimumAmount: { type: GraphQLInt },
    amountType: { type: GraphQLString },
    maxQuantityPerUser: { type: GraphQLInt },
    goal: {
      type: GraphQLInt,
      description: 'amount that you are trying to raise with this tier',
    },
    password: { type: GraphQLString },
    settings: { type: GraphQLJSON },
    startsAt: {
      type: GraphQLString,
      description: 'Start of the campaign',
    },
    endsAt: {
      type: GraphQLString,
      description: 'End of the campaign',
    },
  }),
});

export const OrderInputType = new GraphQLInputObjectType({
  name: 'OrderInputType',
  description: 'Input type for OrderType',
  fields: () => ({
    id: { type: GraphQLInt },
    quantity: {
      type: GraphQLInt,
      defaultValue: 1,
    },
    totalAmount: { type: GraphQLInt },
    hostFeePercent: { type: GraphQLInt },
    platformFeePercent: { type: GraphQLInt },
    currency: { type: GraphQLString },
    interval: { type: GraphQLString },
    description: { type: GraphQLString },
    publicMessage: { type: GraphQLString },
    privateMessage: { type: GraphQLString },
    paymentMethod: { type: PaymentMethodInputType },
    matchingFund: {
      type: GraphQLString,
      description: 'The first part of the UUID of the PaymentMethod that can be used to match the donation',
    },
    referral: {
      type: CollectiveAttributesInputType,
      description: 'The referral collective',
    },
    user: { type: UserInputType },
    fromCollective: { type: CollectiveAttributesInputType },
    collective: { type: new GraphQLNonNull(CollectiveAttributesInputType) },
    tier: { type: TierInputType },
    customFields: { type: new GraphQLList(CustomFieldsInputType) },
    recaptchaToken: { type: GraphQLString },
    // For taxes
    taxAmount: {
      type: GraphQLInt,
      description: 'The amount of taxes that were included in totalAmount',
      defaultValue: 0,
    },
    countryISO: {
      type: GraphQLString,
      description: 'User country, to know which tax applies',
    },
    taxIDNumber: {
      type: GraphQLString,
      description: 'User tax ID number',
    },
  }),
});

export const CommentInputType = new GraphQLInputObjectType({
  name: 'CommentInputType',
  description: 'Input type for CommentType',
  fields: () => ({
    id: { type: GraphQLInt },
    markdown: { type: GraphQLString },
    html: { type: GraphQLString },
    FromCollectiveId: { type: new GraphQLNonNull(GraphQLInt) },
    CollectiveId: { type: new GraphQLNonNull(GraphQLInt) },
    ExpenseId: { type: GraphQLInt },
    UpdateId: { type: GraphQLInt },
  }),
});

export const CommentAttributesInputType = new GraphQLInputObjectType({
  name: 'CommentAttributesInputType',
  description: 'Input type for CommentType',
  fields: () => ({
    id: { type: GraphQLInt },
    markdown: { type: GraphQLString },
    html: { type: GraphQLString },
    FromCollectiveId: { type: GraphQLInt },
    CollectiveId: { type: GraphQLInt },
    ExpenseId: { type: GraphQLInt },
    UpdateId: { type: GraphQLInt },
  }),
});

export const UpdateInputType = new GraphQLInputObjectType({
  name: 'UpdateInputType',
  description: 'Input type for UpdateType',
  fields: () => ({
    id: { type: GraphQLInt },
    views: { type: GraphQLInt },
    slug: { type: GraphQLString },
    title: { type: GraphQLString },
    image: { type: GraphQLString },
    isPrivate: { type: GraphQLBoolean },
    markdown: { type: GraphQLString },
    html: { type: GraphQLString },
    fromCollective: { type: CollectiveAttributesInputType },
    collective: { type: new GraphQLNonNull(CollectiveAttributesInputType) },
    tier: { type: TierInputType },
  }),
});

export const UpdateAttributesInputType = new GraphQLInputObjectType({
  name: 'UpdateAttributesInputType',
  description: 'Input type for UpdateType',
  fields: () => ({
    id: { type: GraphQLInt },
    views: { type: GraphQLInt },
    slug: { type: GraphQLString },
    title: { type: GraphQLString },
    image: { type: GraphQLString },
    isPrivate: { type: GraphQLBoolean },
    markdown: { type: GraphQLString },
    html: { type: GraphQLString },
    fromCollective: { type: CollectiveAttributesInputType },
    tier: { type: TierInputType },
  }),
});

export const ExpenseInputType = new GraphQLInputObjectType({
  name: 'ExpenseInputType',
  description: 'Input type for ExpenseType',
  fields: () => {
    return {
      id: { type: GraphQLInt },
      amount: { type: GraphQLInt },
      currency: { type: GraphQLString },
      createdAt: { type: DateString },
      incurredAt: { type: DateString },
      description: { type: GraphQLString },
      category: { type: GraphQLString },
      status: { type: GraphQLString },
      payoutMethod: {
        type: GraphQLString,
        description: 'Can be paypal, donation, manual, other',
      },
      privateMessage: { type: GraphQLString },
      attachment: { type: GraphQLString },
      user: { type: UserInputType },
      collective: { type: CollectiveAttributesInputType },
    };
  },
});

export const InvoiceInputType = new GraphQLInputObjectType({
  name: 'InvoiceInputType',
  description: 'Input dates and collectives for Invoice',
  fields: () => {
    return {
      dateFrom: { type: IsoDateString },
      dateTo: { type: IsoDateString },
      collectiveSlug: { type: GraphQLString },
      fromCollectiveSlug: { type: GraphQLString },
    };
  },
});
<|endoftext|>


<commit_before>/* Author: Saurabh Kumar
   Last Modified: Feb 20, 2012
****************************/

var debug = true;

$(document).ready(function(){

	log("App started");
	var frame = $('#containter-frame');

	//hide document default scroll-bar
	document.body.style.overflow = 'hidden';

	frame.load(resizeIframe);
	$(window).resize(resizeIframe);

	function resizeIframe() {
    	var h = $(window).height();
    	var w = $(window).width();
    	frame.height(h);
    	frame.width(w);
	}
});

function log (str) {
		// debug log event...
	if (debug) {console.log(str);};
}<commit_msg>fixed misinterpretation of 'document'/'window' height<commit_after>/* Author: Saurabh Kumar
   Last Modified: Feb 20, 2012
****************************/

var debug = false;

$(document).ready(function(){

	log("App started");
	var frame = $('#containter-frame');

	//hide document default scroll-bar
	document.body.style.overflow = 'hidden';

	frame.load(resizeIframe);
	$(window).resize(resizeIframe);

	function resizeIframe() {
    	var w, h;

 		if($.browser.mozilla){
  			h = $(window).height();
    		w = $(window).width();
  			log("firefox");
  		}else{
  			h = $(document).height();
    		w = $(document).width();
    		log("non-firefox");
  		}

    	frame.height(h);
    	frame.width(w);
	}
});

function log (str) {
		// debug log event...
	if (debug) {console.log(str);};
}<|endoftext|>


<commit_before>import styles from './header.mss';

/*****************************************************************************/
/* Header: Event Handlers */
/*****************************************************************************/
Template.Header.events({
});

/*****************************************************************************/
/* Header: Helpers */
/*****************************************************************************/
Template.Header.helpers({
  styles: styles,
  showLoginButtons: () => {
    return Template.instance().showLoginButtons.get();
  }
});

/*****************************************************************************/
/* Header: Lifecycle Hooks */
/*****************************************************************************/
Template.Header.onCreated(function () {
  let template = Template.instance();
  template.showLoginButtons = new ReactiveVar(true);
  Meteor.call('server/getConfig', 'showLoginButtons', function (err, response) {
    if (!err) {
      template.showLoginButtons.set(response.value == 'true');
    } else {
      /*$.notify({
      	message: err,
        icon: 'glyphicon glyphicon-warning-sign'
      },{
      	type: 'danger'
      });*/
      console.error(err);
    }
  });
});

Template.Header.onRendered(function () {
});

Template.Header.onDestroyed(function () {
});
<commit_msg>Temporarily disable login buttons.<commit_after>import styles from './header.mss';

/*****************************************************************************/
/* Header: Event Handlers */
/*****************************************************************************/
Template.Header.events({
});

/*****************************************************************************/
/* Header: Helpers */
/*****************************************************************************/
Template.Header.helpers({
  styles: styles,
  showLoginButtons: () => {
    return false;
    // return Template.instance().showLoginButtons.get();
  }
});

/*****************************************************************************/
/* Header: Lifecycle Hooks */
/*****************************************************************************/
Template.Header.onCreated(function () {
  // let template = Template.instance();
  // template.showLoginButtons = new ReactiveVar(true);
  // Meteor.call('server/getConfig', 'showLoginButtons', function (err, response) {
  //   if (!err) {
  //     template.showLoginButtons.set(response.value == 'true');
  //   } else {
  //     $.notify({
  //     	message: err,
  //       icon: 'glyphicon glyphicon-warning-sign'
  //     },{
  //     	type: 'danger'
  //     });
  //     console.error(err);
  //   }
  // });
});

Template.Header.onRendered(function () {
});

Template.Header.onDestroyed(function () {
});
<|endoftext|>


<commit_before>/**
*
* RealWorldItem
*
*/

import React, {PropTypes} from 'react';
import ReactDOM from 'react-dom';
import styled from 'styled-components';

import ContentBlock from 'components/ContentBlock';
import LatinThemeProvider from 'components/LatinThemeProvider';
// positions;
const TOP = [0,2];
const BOTTOM = [1,3];
const LEFT = [0,2];
const RIGHT = [1,3];

const IMAGE_PREFIX = "https://beautifulrising.org/assets/content/";
const getSvgOverlay = (type) => {
  return require('assets/images/patterns/snapshotoverlay/' + type + '.svg')
};

const ImageBackground = styled.div`
  background-image: url(${props=>IMAGE_PREFIX+props.image});
  background-position: center center;
  opacity: 1;
  width: 100%;
  height: 300px;
  background-size: cover;
  position: relative;
  z-index: 0;
`;

const ImageBackgroundTop =styled(ImageBackground)`
  display: ${props=> props.pos%2==1 ? 'block' : 'none' };
`;
const ImageBackgroundBottom =styled(ImageBackground)`
  display: ${props=> props.pos%2==1 ? 'none' : 'block' };
  margin-top: ${props=>props.marginTop - 30}px;
`;

const RealWorldItemContainer = styled.div`
    // min-height: 300px;
    // position: relative;
    // margin-bottom: 30px;
    text-align: left;
    width: 100%;
    padding: 22px;
    direction: ltr;
    padding-bottom: 0;
    padding-top: 36px;
    margin-top: ${props=> props.pos%2==1 ? '0' : '-22px' };
    * {
      direction: ltr;
    }

    &::after {
      content: ' ';
      display: block;
    }
`;

const Example = styled.div`
  padding: 5px 10px;
  background-color: white;
  position: relative;
  z-index: 100;
  font-size: 12px;
  width: 342px;
  border: 2px solid black;

  ${props=> {
    if(props.pos % 2 == 1) {
      return `
      margin-top: -22px;
      left: calc(100% - 322px);
    `

    } else {
      return `
        margin-left: -20px;
        bottom: -20px;
      `;
    }

  }}
`;
const ExampleTitle = styled.h5`

  margin: 0;
  padding: 0;
  font-size: 14px;
  line-height: 22px;
  font-weight: 800; font-family: 'Avenir', sans-serif;
  letter-spacing: 0;
  a {
    color: black;
    text-decoration: none;
    text-transform: uppercase;
  }
`;
const ExampleDescription = styled(ContentBlock)`
  font-style: italic;
  margin: 5px 0 0;
  padding: 0;
  font-size: 12px;
  line-height: 18px;

`;

class RealWorldItem extends React.PureComponent {

  constructor(props) {
    super(props);
    this.state = {
      exampleHeight: 0
    }
  }
  componentDidMount() {
    var node = ReactDOM.findDOMNode(this.refs.example);

    this.setState({ exampleHeight: node.clientHeight });
  }

  render() {
    return (
      <LatinThemeProvider>
        <RealWorldItemContainer  pos={this.props.pos}>
          <ImageBackgroundTop type={this.props.type} image={this.props.image} pos={this.props.pos}/>
            <Example ref={'example'} pos={this.props.pos}>
              <ContentBlock>
                <ExampleTitle>

                    {this.props.title}

                </ExampleTitle>
              </ContentBlock>
                <ExampleDescription>
                  {this.props.description}
                </ExampleDescription>
            </Example>
          <ImageBackgroundBottom type={this.props.type} image={this.props.image}
                pos={this.props.pos} />
        </RealWorldItemContainer>
      </LatinThemeProvider>
    );
  }

}

RealWorldItem.propTypes = {
  link: PropTypes.string.isRequired,
  description: PropTypes.string.isRequired,
  title: PropTypes.string.isRequired
};

export default RealWorldItem;
<commit_msg>Mobile: the real world examples caption box is getting cut off on the right hand side https://3.basecamp.com/3161453/buckets/3412210/todos/626085808<commit_after>/**
*
* RealWorldItem
*
*/

import React, {PropTypes} from 'react';
import ReactDOM from 'react-dom';
import styled from 'styled-components';

import ContentBlock from 'components/ContentBlock';
import LatinThemeProvider from 'components/LatinThemeProvider';
// positions;
const TOP = [0,2];
const BOTTOM = [1,3];
const LEFT = [0,2];
const RIGHT = [1,3];

const IMAGE_PREFIX = "https://beautifulrising.org/assets/content/";
const getSvgOverlay = (type) => {
  return require('assets/images/patterns/snapshotoverlay/' + type + '.svg')
};

const ImageBackground = styled.div`
  background-image: url(${props=>IMAGE_PREFIX+props.image});
  background-position: center center;
  opacity: 1;
  width: 100%;
  height: 300px;
  background-size: cover;
  position: relative;
  z-index: 0;
`;

const ImageBackgroundTop =styled(ImageBackground)`
  display: ${props=> props.pos%2==1 ? 'block' : 'none' };
`;
const ImageBackgroundBottom =styled(ImageBackground)`
  display: ${props=> props.pos%2==1 ? 'none' : 'block' };
  margin-top: ${props=>props.marginTop - 30}px;
`;

const RealWorldItemContainer = styled.div`
    // min-height: 300px;
    // position: relative;
    // margin-bottom: 30px;
    text-align: left;
    width: 100%;
    padding: 22px;
    direction: ltr;
    padding-bottom: 0;
    padding-top: 36px;
    margin-top: ${props=> props.pos%2==1 ? '0' : '-22px' };
    * {
      direction: ltr;
    }

    &::after {
      content: ' ';
      display: block;
    }
`;

const Example = styled.div`
  padding: 5px 10px;
  background-color: white;
  position: relative;
  z-index: 100;
  font-size: 12px;
  width: 100%;
  max-width: 342px;
  border: 2px solid black;

  ${props=> {
    if(props.pos % 2 == 1) {
      return `
      margin-top: -22px;
      left: calc(100% - 322px);
      @media(max-width: 1170px) {
        left: -22px;
        // left: auto;
      }
    `

    } else {
      return `
        margin-left: -20px;
        bottom: -20px;
      `;
    }

  }}
`;
const ExampleTitle = styled.h5`

  margin: 0;
  padding: 0;
  font-size: 14px;
  line-height: 22px;
  font-weight: 800; font-family: 'Avenir', sans-serif;
  letter-spacing: 0;
  a {
    color: black;
    text-decoration: none;
    text-transform: uppercase;
  }
`;
const ExampleDescription = styled(ContentBlock)`
  font-style: italic;
  margin: 5px 0 0;
  padding: 0;
  font-size: 12px;
  line-height: 18px;

`;

class RealWorldItem extends React.PureComponent {

  constructor(props) {
    super(props);
    this.state = {
      exampleHeight: 0
    }
  }
  componentDidMount() {
    var node = ReactDOM.findDOMNode(this.refs.example);

    this.setState({ exampleHeight: node.clientHeight });
  }

  render() {
    return (
      <LatinThemeProvider>
        <RealWorldItemContainer  pos={this.props.pos}>
          <ImageBackgroundTop type={this.props.type} image={this.props.image} pos={this.props.pos}/>
            <Example ref={'example'} pos={this.props.pos}>
              <ContentBlock>
                <ExampleTitle>

                    {this.props.title}

                </ExampleTitle>
              </ContentBlock>
                <ExampleDescription>
                  {this.props.description}
                </ExampleDescription>
            </Example>
          <ImageBackgroundBottom type={this.props.type} image={this.props.image}
                pos={this.props.pos} />
        </RealWorldItemContainer>
      </LatinThemeProvider>
    );
  }

}

RealWorldItem.propTypes = {
  link: PropTypes.string.isRequired,
  description: PropTypes.string.isRequired,
  title: PropTypes.string.isRequired
};

export default RealWorldItem;
<|endoftext|>


<commit_before>(function(angular, undefined) {
	'use strict';

	/*
	 * Home Controller
	 */
	angular
		.module('app')
		.controller('HomeController', HomeController);

	HomeController.$inject = ['$scope', 'Geocoder', 'Map'];

	function HomeController($scope, Geocoder, Map) {

		var map_marker = '/img/target.png';

		function _init() {

			$scope.year 		 = (new Date()).getFullYear();
			$scope.zoom 		 = 1;
			$scope.zooms 		 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18];
			$scope.latitude  = 0;
			$scope.longitude = 0;
			$scope.startLonlat = { lon: 0, lat: 0 };

			$scope.baselayer  = 1;
			$scope.separator  = 'comma';
			$scope.projection = 'EPSG:4326';
			$scope.defaultProjection = 'EPSG:4326';

			Map.init({
				id: 'map',
				startZoom: $scope.zoom,
				startLonlat: $scope.startLonlat
			});

			Map.getActualZoom(function(zoom) {
				$scope.zoom = zoom;
				_apply();
			});

			Map.enableDragPoint(function(point) {
				_updateValues(point);
			});

			$scope.dropMarker();
			Map.showPopup($scope.startLonlat, 'Drag me to update the values');
		}

		function _apply() {
			if(!$scope.$$phase) $scope.$apply();
		}

		function _separator() {

			switch($scope.separator) {
				case 'space': return ' ';
				case 'comma': return ', ';
			}
		}

		function _updateValues(point) {

			$scope.actualPoint = point;

			point = Map.transform(point, 'EPSG:900913', $scope.defaultProjection);

			if($scope.projection !== $scope.defaultProjection) {
				point = Map.transform(point, $scope.defaultProjection, $scope.projection);
			}

			var s = _separator();

			$scope.longitude = point.lon;
			$scope.latitude  = point.lat;
			$scope.latlon = point.lat + s + point.lon;
			$scope.lonlat = point.lon + s + point.lat;

			var content = 'Longitude' + s + 'Latitude
' + point.lon + s + point.lat + '';
			Map.showPopup($scope.actualPoint, content);

			_apply();
		}

		function _addMarker(point, opts) {

			opts = opts || {};
			point.icon = map_marker;

			Map.addPoint(point, { layer: 'position' });

			if(opts.hasOwnProperty('center') && opts.center) {
				Map.setCenterMap(point, opts.zoom);
			}

			_updateValues(point);
		}

		$scope.dropMarker = function(lonlat) {
			lonlat = lonlat || Map.getCenter();
			_addMarker(lonlat);
		};

		$scope.getPosition = function() {
			$scope.gettingPosition = true;

			Map.getPosition(function(point) {
				_addMarker(point, { center: true, zoom: 14 });
			}, function(errorMessage) {
				alert(errorMessage);
			}, function() {
				// always execute after success and error
				$scope.gettingPosition = false;
			});
		};

		$scope.updateValues = function() {
			_updateValues($scope.actualPoint);
		};

		$scope.searchPlace = function(query) {
			$scope.searchingPlaces = true;

			Geocoder.searchPlace(query)
				.success(function(response) {
					$scope.places = response.results;
					$scope.searchingPlaces = false;
					_apply();
				});
		};

		$scope.selectPlace = function(place) {
			$scope.places 		= [];
			$scope.queryPlace	= '';

			var point = {
				lon: place.geometry.location.lng,
				lat: place.geometry.location.lat
			};
			point = Map.transform(point, $scope.defaultProjection, 'EPSG:900913');

			_addMarker(point, { center: true, zoom: 13 });
		};

		$scope.changeZoom = function(zoom) {
			Map.setZoom(zoom);
		};

		$scope.zoomIn = function() {
			Map.zoomIn();
		};

		$scope.zoomOut = function() {
			Map.zoomOut();
		};

		$scope.changeBaselayer = function(baselayer) {
			Map.setBaseLayer(baselayer);
		};

		_init();
	}

})(window.angular);
<commit_msg>use geolocation on start<commit_after>(function(angular, undefined) {
	'use strict';

	/*
	 * Home Controller
	 */
	angular
		.module('app')
		.controller('HomeController', HomeController);

	HomeController.$inject = ['$scope', 'Geocoder', 'Map'];

	function HomeController($scope, Geocoder, Map) {

		var map_marker = '/img/target.png';

		function _init() {

			$scope.year 		 = (new Date()).getFullYear();
			$scope.zoom 		 = 1;
			$scope.zooms 		 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18];
			$scope.latitude  = 0;
			$scope.longitude = 0;
			$scope.startLonlat = { lon: 0, lat: 0 };

			$scope.baselayer  = 1;
			$scope.separator  = 'comma';
			$scope.projection = 'EPSG:4326';
			$scope.defaultProjection = 'EPSG:4326';

			Map.init({
				id: 'map',
				startZoom: $scope.zoom,
				startLonlat: $scope.startLonlat
			});

			Map.getActualZoom(function(zoom) {
				$scope.zoom = zoom;
				_apply();
			});

			Map.enableDragPoint(function(point) {
				_updateValues(point);
			});

			$scope.dropMarker();
			Map.showPopup($scope.startLonlat, 'Drag me to update the values');

			$scope.getPosition();
		}

		function _apply() {
			if(!$scope.$$phase) $scope.$apply();
		}

		function _separator() {

			switch($scope.separator) {
				case 'space': return ' ';
				case 'comma': return ', ';
			}
		}

		function _updateValues(point) {

			$scope.actualPoint = point;

			point = Map.transform(point, 'EPSG:900913', $scope.defaultProjection);

			if($scope.projection !== $scope.defaultProjection) {
				point = Map.transform(point, $scope.defaultProjection, $scope.projection);
			}

			var s = _separator();

			$scope.longitude = point.lon;
			$scope.latitude  = point.lat;
			$scope.latlon = point.lat + s + point.lon;
			$scope.lonlat = point.lon + s + point.lat;

			var content = 'Longitude' + s + 'Latitude
' + point.lon + s + point.lat + '';
			Map.showPopup($scope.actualPoint, content);

			_apply();
		}

		function _addMarker(point, opts) {

			opts = opts || {};
			point.icon = map_marker;

			Map.addPoint(point, { layer: 'position' });

			if(opts.hasOwnProperty('center') && opts.center) {
				Map.setCenterMap(point, opts.zoom);
			}

			_updateValues(point);
		}

		$scope.dropMarker = function(lonlat) {
			lonlat = lonlat || Map.getCenter();
			_addMarker(lonlat);
		};

		$scope.getPosition = function() {
			$scope.gettingPosition = true;

			Map.getPosition(function(point) {
				_addMarker(point, { center: true, zoom: 14 });
			}, function(errorMessage) {
				alert(errorMessage);
			}, function() {
				// always execute after success and error
				$scope.gettingPosition = false;
			});
		};

		$scope.updateValues = function() {
			_updateValues($scope.actualPoint);
		};

		$scope.searchPlace = function(query) {
			$scope.searchingPlaces = true;

			Geocoder.searchPlace(query)
				.success(function(response) {
					$scope.places = response.results;
					$scope.searchingPlaces = false;
					_apply();
				});
		};

		$scope.selectPlace = function(place) {
			$scope.places 		= [];
			$scope.queryPlace	= '';

			var point = {
				lon: place.geometry.location.lng,
				lat: place.geometry.location.lat
			};
			point = Map.transform(point, $scope.defaultProjection, 'EPSG:900913');

			_addMarker(point, { center: true, zoom: 13 });
		};

		$scope.changeZoom = function(zoom) {
			Map.setZoom(zoom);
		};

		$scope.zoomIn = function() {
			Map.zoomIn();
		};

		$scope.zoomOut = function() {
			Map.zoomOut();
		};

		$scope.changeBaselayer = function(baselayer) {
			Map.setBaseLayer(baselayer);
		};

		_init();
	}

})(window.angular);
<|endoftext|>


<commit_before>SURVEY_PERSONAL_DATA_KEY = "PERSONAL_DATA";

SURVEY_FRAMING_EFFECT_KEY = "FRAMING";
SURVEY_CERTAINTY_EFFECT_KEY = "CERTAINTY";
SURVEY_REFLECTION_EFFECT_KEY = "REFLECTION";

// Json object containing the questions for two final surveys
survey_questions = {};

var survey_personal_data = [{
	id: "firstname",
	type: "TEXT",
	options: [{
		label_en: "First Name",
		label_it: "Nome"
	}]
}, {
	id: "lastname",
	type: "TEXT",
	options: [{
		label_en: "Last Name",
		label_it: "Cognome"
	}]
}, {
	question_en: "What's your job?",
	question_it: "Qual è la tua occupazione?",
	id: "job",
	type: "TEXT",
	options: [{
		label_en: "Job",
		label_it: "Occupazione"
	}]
}, {
	question_en: "What's your education level?",
	question_it: "Qual è il tuo titolo di studio?",
	id: "education_level",
	type: "TEXT",
	options: [{
		label_en: "Education level",
		label_it: "Titolo di studio"
	}]
}, {
	id: "age",
	type: "TEXT",
	options: [{
		label_en: "Age",
		label_it: "Età"
	}]
}, {
	question_en: "Gender",
	question_it: "Genere",
	id: "gender",
	type: "RADIO",
	options: [{
		label_en: "Male",
		label_it: "Maschio",
		value: "Male"
	}, {
		label_en: "Female",
		label_it: "Femmina",
		value: "Female"
	}]
}, {
	question_en: "Do you usually play videogames?",
	question_it: "Giochi abitualmente con i videogiochi?",
	id: 5,
	type: "RADIO",
	options: [{
		label_en: "Yes",
		label_it: "Sì",
		value: "Yes"
	}, {
		label_en: "No",
		label_it: "No",
		value: "No"
	}]
}, {
	question_en: "Have you played to money games, in the last year?",
	question_it: "Hai svolto giochi a soldi nell'ultimo anno?",
	id: 6,
	type: "RADIO",
	options: [{
		label_en: "Yes",
		label_it: "Sì",
		value: "Yes"
	}, {
		label_en: "No",
		label_it: "No",
		value: "No"
	}]
}];
survey_questions[SURVEY_PERSONAL_DATA_KEY] = survey_personal_data;
var survey_framing = [{
	question_en: "At the end of games, do you think you're better than when you started?",
	question_it: "Al termine delle partite svolte, ritieni di essere diventato più bravo rispetto a quando hai cominciato a giocare?",
	id: 1,
	type: "RADIO",
	options: [{
		label_en: "No",
		label_it: "No",
		value: "No"
	}, {
		label_en: "Yes",
		label_it: "Sì",
		value: "Yes"
	}]
}, {
	question_en: "Are you satisfied of the points distribution you gained while playing?",
	question_it: "Sei soddisfatto della distribuzione dei punti che hai guadagnato durante le partite?",
	id: 2,
	type: "RADIO",
	options: [{
		label_en: "No",
		label_it: "No",
		value: "No"
	}, {
		label_en: "Yes",
		label_it: "Sì",
		value: "Yes"
	}]
}, {
	question_en: "How satisfied are you with points distribution from 1 to 5?",
	question_it: "Quanto sei soddisfatto della distribuzione dei punti da 1 a 5?",
	id: 3,
	type: "RADIO",
	options: [{
		label_en: "1",
		label_it: "1",
		value: "1"
	}, {
		label_en: "2",
		label_it: "2",
		value: "2"
	}, {
		label_en: "3",
		label_it: "3",
		value: "3"
	}, {
		label_en: "4",
		label_it: "4",
		value: "4"
	}, {
		label_en: "5",
		label_it: "5",
		value: "5"
	}]
}];
survey_questions[SURVEY_FRAMING_EFFECT_KEY] = survey_framing;<commit_msg>Changed question<commit_after>SURVEY_PERSONAL_DATA_KEY = "PERSONAL_DATA";

SURVEY_FRAMING_EFFECT_KEY = "FRAMING";
SURVEY_CERTAINTY_EFFECT_KEY = "CERTAINTY";
SURVEY_REFLECTION_EFFECT_KEY = "REFLECTION";

// Json object containing the questions for two final surveys
survey_questions = {};

var survey_personal_data = [{
	id: "firstname",
	type: "TEXT",
	options: [{
		label_en: "First Name",
		label_it: "Nome"
	}]
}, {
	id: "lastname",
	type: "TEXT",
	options: [{
		label_en: "Last Name",
		label_it: "Cognome"
	}]
}, {
	question_en: "What's your job?",
	question_it: "Qual è la tua occupazione?",
	id: "job",
	type: "TEXT",
	options: [{
		label_en: "Job",
		label_it: "Occupazione"
	}]
}, {
	question_en: "What's your education level?",
	question_it: "Qual è il tuo titolo di studio?",
	id: "education_level",
	type: "TEXT",
	options: [{
		label_en: "Education level",
		label_it: "Titolo di studio"
	}]
}, {
	id: "age",
	type: "TEXT",
	options: [{
		label_en: "Age",
		label_it: "Età"
	}]
}, {
	question_en: "Gender",
	question_it: "Genere",
	id: "gender",
	type: "RADIO",
	options: [{
		label_en: "Male",
		label_it: "Maschio",
		value: "Male"
	}, {
		label_en: "Female",
		label_it: "Femmina",
		value: "Female"
	}]
}, {
	question_en: "Do you usually play videogames?",
	question_it: "Giochi abitualmente con i videogiochi?",
	id: 5,
	type: "RADIO",
	options: [{
		label_en: "Yes",
		label_it: "Sì",
		value: "Yes"
	}, {
		label_en: "No",
		label_it: "No",
		value: "No"
	}]
}, {
	question_en: "Have you played to money games, in the last year?",
	question_it: "Hai svolto giochi a soldi nell'ultimo anno?",
	id: 6,
	type: "RADIO",
	options: [{
		label_en: "Yes",
		label_it: "Sì",
		value: "Yes"
	}, {
		label_en: "No",
		label_it: "No",
		value: "No"
	}]
}];
survey_questions[SURVEY_PERSONAL_DATA_KEY] = survey_personal_data;
var survey_framing = [{
	question_en: "At the end of games, do you think you're better than when you started?",
	question_it: "Al termine delle partite svolte, ritieni di essere diventato più bravo rispetto a quando hai cominciato a giocare?",
	id: 1,
	type: "RADIO",
	options: [{
		label_en: "No",
		label_it: "No",
		value: "No"
	}, {
		label_en: "Yes",
		label_it: "Sì",
		value: "Yes"
	}]
}, {
	question_en: "Are you satisfied of the points distribution you gained while playing?",
	question_it: "Sei contento dei punti che hai guadagnato durante le partite?",
	id: 2,
	type: "RADIO",
	options: [{
		label_en: "No",
		label_it: "No",
		value: "No"
	}, {
		label_en: "Yes",
		label_it: "Sì",
		value: "Yes"
	}]
}, {
	question_en: "How satisfied are you with points distribution from 1 to 5?",
	question_it: "Quanto sei soddisfatto della distribuzione dei punti da 1 a 5?",
	id: 3,
	type: "RADIO",
	options: [{
		label_en: "1",
		label_it: "1",
		value: "1"
	}, {
		label_en: "2",
		label_it: "2",
		value: "2"
	}, {
		label_en: "3",
		label_it: "3",
		value: "3"
	}, {
		label_en: "4",
		label_it: "4",
		value: "4"
	}, {
		label_en: "5",
		label_it: "5",
		value: "5"
	}]
}];
survey_questions[SURVEY_FRAMING_EFFECT_KEY] = survey_framing;<|endoftext|>


<commit_before>/**
 * Images
 *
 * All code related to the Images collection goes here.
 */

Images = new Meteor.Collection('images');

// Allow/Deny
Images.allow({
  insert: function (userId, doc) {
    return true;
  },

  update:  function (userId, doc, fieldNames, modifier) {
    return true;
  },

  remove:  function (userId, doc) {
    return true;
  },
});

// Attach schema for autoforms
var schema = Images.attachSchema(new SimpleSchema({
  dsLocId: {
    type: Number,
    optional: false,
    autoform: {
      omit:true,
    },
  },
  generalLocationDs: {
    type: String,
    optional: false,
    autoform: {
      omit:true,
    },
  },
  isoDate: {
    type: String,
    label: function () {
      return getToolTipLabel('Date ( yyyy-mm-dd )', 'Use 0 to mark no data (1987-01-00 = January, 1987)   Use u to mark uncertainty (19uu = 1900s)');
    },

    defaultValue: '0000-00-00',
    max:10,
    min:10,
    optional: false,
    custom: function () {
      if (!this.value.match(/([0-9u]{4})-(\d{2})-(\d{2})/)) {
        return 'isoDateInvalid';
      }
    },
  },
  dsNumber: {
    type: String,
    label: function () {
      return getToolTipLabel('DS Number', 'Character limit: 15. (e.g. ds0123456)');
    },

    defaultValue: '',
    max:15,
    optional: true,
  },
  imageFilePaths: {
      type: [Object],
      label: function () {
        return getToolTipLabel('Image File', 'Max filesize is 10mb. Allowed file-types are PNGs and JPGs.');
      },

      optional: true, // (optional)
      custom: function () {
        var fileName = this.value[0].filename;
        fileName = fileName.toLowerCase();
        if (!fileName.match(/\.(jpg|jpeg|png|gif)$/)) {
          return 'wrongImageType';
        }
      },

      autoform: {
        type: 'slingshotFileUpload', // (required)
        removeLabel: 'Remove', // (optional, defaults to "Remove")
        afFieldInput: {
          // Specify which slingshotdirective to present as thumbnail when  this picture is uploaded, you can use the "key" or "directive".
          thumbnail: 'original',
          accept: ['image/png', 'image/jpeg', 'image/gif'],
          slingshotdirective: {
            original: {
              directive: 'originalImageDirective',
            },
            thumb: { // <-- This is the "key" for the "thumb" version.
              directive: 'thumbImageDirective',
              onBeforeUpload: function (file, callback) {

                // Create a thumbnail 175x175 size version.
                Resizer.resize(file, { width: 175, height: 175, cropSquare: false }, function (err, file) {
                  if (err) {
                    console.error(err);
                  }

                  callback(file);

                });
              },
            },
          },
        },
      },
    },

  // NOTICE! These are required for the above type: slingshot [Object].
  'imageFilePaths.$.key': { type: String },
  'imageFilePaths.$.filename': { type: String },
  'imageFilePaths.$.src': { type: String },
  'imageFilePaths.$.directive': { type: String },

  active: {
    type: Boolean,
    label: 'Active (Uncheck to hide)',
    optional: false,
    autoform: {
      afFieldInput: {
        type: 'boolean-checkbox',
        defaultValue: true,
      },
    },
  },

  title: {
    type: String,
    label: function () {
      return getToolTipLabel('Title', 'Character limit: 150. Only displays if Creation place is left empty.');
    },

    defaultValue: '',
    max:150,
    optional: true,
  },
  creationPlace: {
    type: String,
    label: function () {
      return getToolTipLabel('Creation place', 'Character limit: 60.');
    },

    defaultValue: '',
    max:60,
    optional: true,
  },
  creditLine: {
    type: String,
    label: function () {
      return getToolTipLabel('Credit line', 'Character limit: 130.');
    },

    defaultValue: '',
    max:130,
    optional: true,
  },
  labelTextEnglish: {
    type: String,
    label: function () {
      return getToolTipLabel('English label', 'Character limit: 275.');
    },

    defaultValue: '',
    optional: true,
    max:275,
    autoform: {
      rows: 3,
    },
  },
  labelTextSpanish: {
    type: String,
    label: function () {
      return getToolTipLabel('Spanish label', 'Character limit: 340.');
    },

    defaultValue: '',
    optional: true,
    max:340,
    autoform: {
      rows: 3,
    },
  },
  expandedHeight: {
    type: Number,
    optional: true,
    autoform: {
      omit:true,
    },
  },
  expandedWidth: {
    type: Number,
    optional: true,
    autoform: {
      omit:true,
    },
  },
  expandedAspectRatio: {
    type: Number,
    decimal: true,
    optional: true,
    autoform: {
      omit:true,
    },
  },
  thumbWidth: {
    type: Number,
    optional: true,
    autoform: {
      omit:true,
    },
  },
  thumbHeight: {
    type: Number,
    optional: true,
    autoform: {
      omit:true,
    },
  },
  thumbAspectRatio: {
    type: Number,
    decimal: true,
    optional: true,
    autoform: {
      omit:true,
    },
  },

}));

SimpleSchema.messages({
  wrongImageType: 'Invalid file type. Please use .png, .jpg, or .jpeg.',
  isoDateInvalid: 'Use format YYYY-MM-DD (1968-02-23). Zeros denote no data (1987-01-00 = January, 1987) Within year, "u"s denote uncertainty (19uu = 1900s)',
});

function getToolTipLabel(labelTxt, tipTxt) {
  return new Spacebars.SafeString(labelTxt + ' ');
}
<commit_msg>Temporary hack for deploy<commit_after>/**
 * Images
 *
 * All code related to the Images collection goes here.
 */

Images = new Meteor.Collection('images');

// Allow/Deny
Images.allow({
  insert: function (userId, doc) {
    return true;
  },

  update:  function (userId, doc, fieldNames, modifier) {
    return true;
  },

  remove:  function (userId, doc) {
    return true;
  },
});

// Attach schema for autoforms
var schema = Images.attachSchema(new SimpleSchema({
  dsLocId: {
    type: Number,
    // Temporary hack. This should be set back to false.
    // There is something wrong with one of the images in the database
    optional: true,
    autoform: {
      omit:true,
    },
  },
  generalLocationDs: {
    type: String,
    optional: false,
    autoform: {
      omit:true,
    },
  },
  isoDate: {
    type: String,
    label: function () {
      return getToolTipLabel('Date ( yyyy-mm-dd )', 'Use 0 to mark no data (1987-01-00 = January, 1987)   Use u to mark uncertainty (19uu = 1900s)');
    },

    defaultValue: '0000-00-00',
    max:10,
    min:10,
    optional: false,
    custom: function () {
      if (!this.value.match(/([0-9u]{4})-(\d{2})-(\d{2})/)) {
        return 'isoDateInvalid';
      }
    },
  },
  dsNumber: {
    type: String,
    label: function () {
      return getToolTipLabel('DS Number', 'Character limit: 15. (e.g. ds0123456)');
    },

    defaultValue: '',
    max:15,
    optional: true,
  },
  imageFilePaths: {
      type: [Object],
      label: function () {
        return getToolTipLabel('Image File', 'Max filesize is 10mb. Allowed file-types are PNGs and JPGs.');
      },

      optional: true, // (optional)
      custom: function () {
        var fileName = this.value[0].filename;
        fileName = fileName.toLowerCase();
        if (!fileName.match(/\.(jpg|jpeg|png|gif)$/)) {
          return 'wrongImageType';
        }
      },

      autoform: {
        type: 'slingshotFileUpload', // (required)
        removeLabel: 'Remove', // (optional, defaults to "Remove")
        afFieldInput: {
          // Specify which slingshotdirective to present as thumbnail when  this picture is uploaded, you can use the "key" or "directive".
          thumbnail: 'original',
          accept: ['image/png', 'image/jpeg', 'image/gif'],
          slingshotdirective: {
            original: {
              directive: 'originalImageDirective',
            },
            thumb: { // <-- This is the "key" for the "thumb" version.
              directive: 'thumbImageDirective',
              onBeforeUpload: function (file, callback) {

                // Create a thumbnail 175x175 size version.
                Resizer.resize(file, { width: 175, height: 175, cropSquare: false }, function (err, file) {
                  if (err) {
                    console.error(err);
                  }

                  callback(file);

                });
              },
            },
          },
        },
      },
    },

  // NOTICE! These are required for the above type: slingshot [Object].
  'imageFilePaths.$.key': { type: String },
  'imageFilePaths.$.filename': { type: String },
  'imageFilePaths.$.src': { type: String },
  'imageFilePaths.$.directive': { type: String },

  active: {
    type: Boolean,
    label: 'Active (Uncheck to hide)',
    optional: false,
    autoform: {
      afFieldInput: {
        type: 'boolean-checkbox',
        defaultValue: true,
      },
    },
  },

  title: {
    type: String,
    label: function () {
      return getToolTipLabel('Title', 'Character limit: 150. Only displays if Creation place is left empty.');
    },

    defaultValue: '',
    max:150,
    optional: true,
  },
  creationPlace: {
    type: String,
    label: function () {
      return getToolTipLabel('Creation place', 'Character limit: 60.');
    },

    defaultValue: '',
    max:60,
    optional: true,
  },
  creditLine: {
    type: String,
    label: function () {
      return getToolTipLabel('Credit line', 'Character limit: 130.');
    },

    defaultValue: '',
    max:130,
    optional: true,
  },
  labelTextEnglish: {
    type: String,
    label: function () {
      return getToolTipLabel('English label', 'Character limit: 275.');
    },

    defaultValue: '',
    optional: true,
    max:275,
    autoform: {
      rows: 3,
    },
  },
  labelTextSpanish: {
    type: String,
    label: function () {
      return getToolTipLabel('Spanish label', 'Character limit: 340.');
    },

    defaultValue: '',
    optional: true,
    max:340,
    autoform: {
      rows: 3,
    },
  },
  expandedHeight: {
    type: Number,
    optional: true,
    autoform: {
      omit:true,
    },
  },
  expandedWidth: {
    type: Number,
    optional: true,
    autoform: {
      omit:true,
    },
  },
  expandedAspectRatio: {
    type: Number,
    decimal: true,
    optional: true,
    autoform: {
      omit:true,
    },
  },
  thumbWidth: {
    type: Number,
    optional: true,
    autoform: {
      omit:true,
    },
  },
  thumbHeight: {
    type: Number,
    optional: true,
    autoform: {
      omit:true,
    },
  },
  thumbAspectRatio: {
    type: Number,
    decimal: true,
    optional: true,
    autoform: {
      omit:true,
    },
  },

}));

SimpleSchema.messages({
  wrongImageType: 'Invalid file type. Please use .png, .jpg, or .jpeg.',
  isoDateInvalid: 'Use format YYYY-MM-DD (1968-02-23). Zeros denote no data (1987-01-00 = January, 1987) Within year, "u"s denote uncertainty (19uu = 1900s)',
});

function getToolTipLabel(labelTxt, tipTxt) {
  return new Spacebars.SafeString(labelTxt + ' ');
}
<|endoftext|>


<commit_before>/*
 * Copyright 2016 Red Hat Inc. All rights reserved.
 *
 * 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
 *
 *     http://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.
 */
'use strict';

const URL = require('url');

module.exports = function (keycloak) {
  return function postAuth (request, response, next) {
    if (!request.query.auth_callback) {
      return next();
    }

    if (request.query.error) {
      return keycloak.accessDenied(request, response, next);
    }

    keycloak.getGrantFromCode(request.query.code, request, response)
      .then(grant => {
        let urlParts = {
          pathname: request.path,
          query: request.query
        };

        delete urlParts.query.code;
        delete urlParts.query.auth_callback;
        delete urlParts.query.state;

        let cleanUrl = URL.format(urlParts);

        request.kauth.grant = grant;
        try {
          keycloak.authenticated(request);
        } catch (err) {
          console.log(err);
        }
        response.redirect(cleanUrl);
      }).catch((err) => {
        keycloak.accessDenied(request, response);
        console.error('Could not obtain grant code: ' + err);
      });
  };
};
<commit_msg>Fix for [KEYCLOAK-6171] Node.js adapter doesn't remove "session_state" from URL after login<commit_after>/*
 * Copyright 2016 Red Hat Inc. All rights reserved.
 *
 * 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
 *
 *     http://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.
 */
'use strict';

const URL = require('url');

module.exports = function (keycloak) {
  return function postAuth (request, response, next) {
    if (!request.query.auth_callback) {
      return next();
    }

    if (request.query.error) {
      return keycloak.accessDenied(request, response, next);
    }

    keycloak.getGrantFromCode(request.query.code, request, response)
      .then(grant => {
        let urlParts = {
          pathname: request.path,
          query: request.query
        };

        delete urlParts.query.code;
        delete urlParts.query.auth_callback;
        delete urlParts.query.state;
        delete urlParts.query.session_state;

        let cleanUrl = URL.format(urlParts);

        request.kauth.grant = grant;
        try {
          keycloak.authenticated(request);
        } catch (err) {
          console.log(err);
        }
        response.redirect(cleanUrl);
      }).catch((err) => {
        keycloak.accessDenied(request, response);
        console.error('Could not obtain grant code: ' + err);
      });
  };
};
<|endoftext|>


<commit_before>(function() {
  'use strict';

  function listenToClick(element, name, fn) {
    if (document.addEventListener) {
      element.addEventListener(name, fn, false);
    } else {
      element.attachEvent((name === 'click') ? 'onclick' : name, fn);
    }
  }

  function hasClass(el, className) {
    if (el.classList)
      return el.classList.contains(className)
    else
      return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'))
  }

  function my_addClass(el, className) {
    if (el.classList)
      el.classList.add(className)
    else if (!hasClass(el, className)) el.className += " " + className
  }

  function my_removeClass(el, className) {
    if (el.classList)
      el.classList.remove(className)
    else if (hasClass(el, className)) {
      var reg = new RegExp('(\\s|^)' + className + '(\\s|$)')
      el.className=el.className.replace(reg, ' ')
    }
  }

  function scrollTop(element, to, duration) {
    var start = element.scrollTop,
        change = to - start,
        currentTime = 0,
        increment = 20;

    var animateScroll = function(){
      currentTime += increment;
      var val = Math.easeInOutQuad(currentTime, start, change, duration);
      element.scrollTop = val;
      if(currentTime < duration) {
        setTimeout(animateScroll, increment);
      }
    };
    animateScroll();
  }

  //t = current time
  //b = start value
  //c = change in value
  //d = duration
  Math.easeInOutQuad = function (t, b, c, d) {
    t /= d/2;
    if (t < 1) return c/2*t*t + b;
    t--;
    return -c/2 * (t*(t-2) - 1) + b;
  }

  function each(o, cb, s){
    var n;
    if (!o){
      return 0;
    }
    s = !s ? o : s;
    if (o instanceof Array){
      // Indexed arrays, needed for Safari
      for (n=0; n<o.length; n++) {
        if (cb.call(s, o[n], n, o) === false){
          return 0;
        }
      }
    } else {
      // Hashtables
      for (n in o){
        if (o.hasOwnProperty(n)) {
          if (cb.call(s, o[n], n, o) === false){
            return 0;
          }
        }
      }
    }
    return 1;
  }

  domready(function() {
    var
      scrollElements,
      inValidRange,
      setVisibility,
      setVisibilityAll,
      resetScroll;

    scrollElements = document.querySelectorAll('[data-scroll-element]');

    inValidRange = function(offset, limit) {
      return offset >= 0 && offset < limit;
    };

    setVisibility = function(element, nextOffset, limit) {
      if(inValidRange(nextOffset, limit)) {
        my_removeClass(element, 'disabled');
      } else {
        my_addClass(element, 'disabled');
      }
    };

    setVisibilityAll = function(elements, newOffset) {
      var
        scrollElement,
        increment,
        nextOffset,
        limit;

      each(elements, function(el) {
        scrollElement = document.querySelector(el.dataset.scrollElement);
        increment  = parseInt(el.dataset.scrollIncrement);
        nextOffset = newOffset + increment;
        limit      = parseInt(scrollElement.dataset.scrollLimit);

        setVisibility(el, nextOffset, limit);
      });
    };

    resetScroll = function(element) {
      element.scrollTop = 0;
      element.dataset.scrollOffset = 0;
    };

    each(document.querySelectorAll('[data-clipboard-target]'), function(el) {
      var
        clipboard,
        notification;

      clipboard = new Clipboard(el);

      var notify = function(clipboardNotification, notificationText) {
        notification = document.getElementById(clipboardNotification.slice(1));
        notification.textContent = notificationText;
        my_addClass(notification, 'in');
        setTimeout(function() {
          my_removeClass(notification, 'in');
        }, 1400);
      };

      var notifySuccess = function(e) {
        notify(e.trigger.dataset.clipboardNotification, "Copied!");
      };

      var notifyFailure = function(e) {
        //if the copy function failed the text should still be selected, so just ask the user to hit ctrl+c
        notify(e.trigger.dataset.clipboardNotification, "Press Ctrl+C to copy");
      };

      clipboard.on('success', notifySuccess);
      clipboard.on('error', notifyFailure);
    });

    each(scrollElements, function(el) {
      var
        element,
        increment,
        limit,
        offset,
        nextOffset,
        newOffset;

      element = document.querySelector(el.dataset.scrollElement);
      increment = parseInt(el.dataset.scrollIncrement);
      limit     = parseInt(element.dataset.scrollLimit.valueOf());
      offset    = parseInt(element.dataset.scrollOffset.valueOf());

      element.dataset.scrollLimit = limit;

      nextOffset = offset + increment;

      setVisibility(el, nextOffset, limit);

      // Force IE to forget previous scroll top value
      resetScroll(element);

      listenToClick(el, 'click', function() {
        offset = parseInt(element.dataset.scrollOffset);

        newOffset = offset + increment;

        if (inValidRange(newOffset, limit)) {
          scrollTop(element, document.getElementById(newOffset).offsetTop, 400);
          element.dataset.scrollOffset = newOffset;

          setVisibilityAll(scrollElements, newOffset);
        }
      });
    });

    each(document.querySelectorAll('[data-moment]'), function(el) {
      var time = moment(parseInt(el.textContent));
      el.textContent = time.fromNow();
    });

    each(document.querySelectorAll('[data-clipboard-target]'), funtction() {
      console.log(window.squatch);
    });
  });

})();
<commit_msg>Start testing event bus<commit_after>(function() {
  'use strict';

  function listenToClick(element, name, fn) {
    if (document.addEventListener) {
      element.addEventListener(name, fn, false);
    } else {
      element.attachEvent((name === 'click') ? 'onclick' : name, fn);
    }
  }

  function hasClass(el, className) {
    if (el.classList)
      return el.classList.contains(className)
    else
      return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'))
  }

  function my_addClass(el, className) {
    if (el.classList)
      el.classList.add(className)
    else if (!hasClass(el, className)) el.className += " " + className
  }

  function my_removeClass(el, className) {
    if (el.classList)
      el.classList.remove(className)
    else if (hasClass(el, className)) {
      var reg = new RegExp('(\\s|^)' + className + '(\\s|$)')
      el.className=el.className.replace(reg, ' ')
    }
  }

  function scrollTop(element, to, duration) {
    var start = element.scrollTop,
        change = to - start,
        currentTime = 0,
        increment = 20;

    var animateScroll = function(){
      currentTime += increment;
      var val = Math.easeInOutQuad(currentTime, start, change, duration);
      element.scrollTop = val;
      if(currentTime < duration) {
        setTimeout(animateScroll, increment);
      }
    };
    animateScroll();
  }

  //t = current time
  //b = start value
  //c = change in value
  //d = duration
  Math.easeInOutQuad = function (t, b, c, d) {
    t /= d/2;
    if (t < 1) return c/2*t*t + b;
    t--;
    return -c/2 * (t*(t-2) - 1) + b;
  }

  function each(o, cb, s){
    var n;
    if (!o){
      return 0;
    }
    s = !s ? o : s;
    if (o instanceof Array){
      // Indexed arrays, needed for Safari
      for (n=0; n<o.length; n++) {
        if (cb.call(s, o[n], n, o) === false){
          return 0;
        }
      }
    } else {
      // Hashtables
      for (n in o){
        if (o.hasOwnProperty(n)) {
          if (cb.call(s, o[n], n, o) === false){
            return 0;
          }
        }
      }
    }
    return 1;
  }

  domready(function() {
    var
      scrollElements,
      inValidRange,
      setVisibility,
      setVisibilityAll,
      resetScroll;

    scrollElements = document.querySelectorAll('[data-scroll-element]');

    inValidRange = function(offset, limit) {
      return offset >= 0 && offset < limit;
    };

    setVisibility = function(element, nextOffset, limit) {
      if(inValidRange(nextOffset, limit)) {
        my_removeClass(element, 'disabled');
      } else {
        my_addClass(element, 'disabled');
      }
    };

    setVisibilityAll = function(elements, newOffset) {
      var
        scrollElement,
        increment,
        nextOffset,
        limit;

      each(elements, function(el) {
        scrollElement = document.querySelector(el.dataset.scrollElement);
        increment  = parseInt(el.dataset.scrollIncrement);
        nextOffset = newOffset + increment;
        limit      = parseInt(scrollElement.dataset.scrollLimit);

        setVisibility(el, nextOffset, limit);
      });
    };

    resetScroll = function(element) {
      element.scrollTop = 0;
      element.dataset.scrollOffset = 0;
    };

    each(document.querySelectorAll('[data-clipboard-target]'), function(el) {
      var
        clipboard,
        notification;

      clipboard = new Clipboard(el);

      var notify = function(clipboardNotification, notificationText) {
        notification = document.getElementById(clipboardNotification.slice(1));
        notification.textContent = notificationText;
        my_addClass(notification, 'in');
        setTimeout(function() {
          my_removeClass(notification, 'in');
        }, 1400);
      };

      var notifySuccess = function(e) {
        notify(e.trigger.dataset.clipboardNotification, "Copied!");
      };

      var notifyFailure = function(e) {
        //if the copy function failed the text should still be selected, so just ask the user to hit ctrl+c
        notify(e.trigger.dataset.clipboardNotification, "Press Ctrl+C to copy");
      };

      clipboard.on('success', notifySuccess);
      clipboard.on('error', notifyFailure);
    });

    each(scrollElements, function(el) {
      var
        element,
        increment,
        limit,
        offset,
        nextOffset,
        newOffset;

      element = document.querySelector(el.dataset.scrollElement);
      increment = parseInt(el.dataset.scrollIncrement);
      limit     = parseInt(element.dataset.scrollLimit.valueOf());
      offset    = parseInt(element.dataset.scrollOffset.valueOf());

      element.dataset.scrollLimit = limit;

      nextOffset = offset + increment;

      setVisibility(el, nextOffset, limit);

      // Force IE to forget previous scroll top value
      resetScroll(element);

      listenToClick(el, 'click', function() {
        offset = parseInt(element.dataset.scrollOffset);

        newOffset = offset + increment;

        if (inValidRange(newOffset, limit)) {
          scrollTop(element, document.getElementById(newOffset).offsetTop, 400);
          element.dataset.scrollOffset = newOffset;

          setVisibilityAll(scrollElements, newOffset);
        }
      });
    });

    each(document.querySelectorAll('[data-moment]'), function(el) {
      var time = moment(parseInt(el.textContent));
      el.textContent = time.fromNow();
    });

    each(document.querySelectorAll('[data-clipboard-target]'), function(el) {
      console.log(window.squatch);
    });
  });

})();
<|endoftext|>


<commit_before>(function() {
  'use strict';

  function listenToClick(element, name, fn) {
    if (document.addEventListener) {
      element.addEventListener(name, fn, false);
    } else {
      element.attachEvent((name === 'click') ? 'onclick' : name, fn);
    }
  }

  function handleClicks(elem, fn) {
    if (document.addEventListener) {
      // For all major browsers, except IE 8 and earlier
      elem.addEventListener("click", fn, false);
      elem.addEventListener("touchstart", fn, false);
    } else if (document.attachEvent) {
      // For IE 8 and earlier versions
      elem.attachEvent("onclick", fn, false);
      elem.attachEvent("touchstart", fn, false);
    }
  };

  function hasClass(el, className) {
    if (el.classList)
      return el.classList.contains(className)
    else
      return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'))
  }

  function my_addClass(el, className) {
    if (el.classList)
      el.classList.add(className)
    else if (!hasClass(el, className)) el.className += " " + className
  }

  function my_removeClass(el, className) {
    if (el.classList)
      el.classList.remove(className)
    else if (hasClass(el, className)) {
      var reg = new RegExp('(\\s|^)' + className + '(\\s|$)')
      el.className=el.className.replace(reg, ' ')
    }
  }

  function scrollTop(element, to, duration) {
    var start = element.scrollTop,
        change = to - start,
        currentTime = 0,
        increment = 20;

    var animateScroll = function(){
      currentTime += increment;
      var val = Math.easeInOutQuad(currentTime, start, change, duration);
      element.scrollTop = val;
      if(currentTime < duration) {
        setTimeout(animateScroll, increment);
      }
    };
    animateScroll();
  }

  //t = current time
  //b = start value
  //c = change in value
  //d = duration
  Math.easeInOutQuad = function (t, b, c, d) {
    t /= d/2;
    if (t < 1) return c/2*t*t + b;
    t--;
    return -c/2 * (t*(t-2) - 1) + b;
  }

  function each(o, cb, s){
    var n;
    if (!o){
      return 0;
    }
    s = !s ? o : s;
    if (o instanceof Array){
      // Indexed arrays, needed for Safari
      for (n=0; n<o.length; n++) {
        if (cb.call(s, o[n], n, o) === false){
          return 0;
        }
      }
    } else {
      // Hashtables
      for (n in o){
        if (o.hasOwnProperty(n)) {
          if (cb.call(s, o[n], n, o) === false){
            return 0;
          }
        }
      }
    }
    return 1;
  }

  domready(function() {

    var scrollElements = document.querySelectorAll('[data-scroll-element]');

    var inValidRange = function(offset, limit) {
      return offset >= 0 && offset < limit;
    };

    var setVisibility = function(element, nextOffset, limit) {
      if(inValidRange(nextOffset, limit)) {
        my_removeClass(element, 'disabled');
      } else {
        my_addClass(element, 'disabled');
      }
    };

    var setVisibilityAll = function(elements, newOffset) {
      var
        scrollElement,
        increment,
        nextOffset,
        limit;

      each(elements, function(el) {
        scrollElement = document.querySelector(el.dataset.scrollElement);
        increment  = parseInt(el.dataset.scrollIncrement);
        nextOffset = newOffset + increment;
        limit      = parseInt(scrollElement.dataset.scrollLimit);

        setVisibility(el, nextOffset, limit);
      });
    };

    var resetScroll = function(element) {
      element.scrollTop = 0;
      element.dataset.scrollOffset = 0;
    };

    each(document.querySelectorAll('[data-clipboard-target]'), function(el) {
      var clipboard = new Clipboard(el);
      var notification;

      var notify = function(clipboardNotification, notificationText) {
        notification = document.getElementById(clipboardNotification.slice(1));
        notification.textContent = notificationText;
        my_addClass(notification, 'in');
        setTimeout(function() {
          my_removeClass(notification, 'in');
        }, 1400);
      };

      var notifySuccess = function(e) {
        notify(e.trigger.dataset.clipboardNotification, "Copied!");
      };

      var notifyFailure = function(e) {
        //if the copy function failed the text should still be selected, so just ask the user to hit ctrl+c
        notify(e.trigger.dataset.clipboardNotification, "Press Ctrl+C to copy");
      };

      clipboard.on('success', notifySuccess);
      clipboard.on('error', notifyFailure);
      handleClicks(el, function(e) {
        if (window.parent.squatch.eventBus) {
          window.parent.squatch.eventBus.dispatch('copy_btn_clicked', e.type);
        }
      });
    });

    each(scrollElements, function(el) {
      var element = document.querySelector(el.dataset.scrollElement);
      var increment = parseInt(el.dataset.scrollIncrement);
      var limit     = parseInt(element.dataset.scrollLimit.valueOf());
      var offset    = parseInt(element.dataset.scrollOffset.valueOf());
      var newOffset;

      element.dataset.scrollLimit = limit;

      var nextOffset = offset + increment;

      setVisibility(el, nextOffset, limit);

      // Force IE to forget previous scroll top value
      resetScroll(element);

      listenToClick(el, 'click', function() {
        offset = parseInt(element.dataset.scrollOffset);

        newOffset = offset + increment;

        if (inValidRange(newOffset, limit)) {
          scrollTop(element, document.getElementById(newOffset).offsetTop, 400);
          element.dataset.scrollOffset = newOffset;

          setVisibilityAll(scrollElements, newOffset);
        }
      });
    });

    each(document.querySelectorAll('[data-moment]'), function(el) {
      var time = moment(parseInt(el.textContent));
      el.textContent = time.fromNow();
    });

    each(document.getElementsByClassName('squatch-header-close'), function(el) {
      handleClicks(el, function(e) {
        if (window.parent.squatch.eventBus) {
          window.parent.squatch.eventBus.dispatch('close_popup', e.type);
        }
      });
    });

    // CTA
    each(document.getElementsByClassName('cta-container'), function(el) {
      el.onclick = function() {
        if (window.parent.squatch.eventBus) {
          window.parent.squatch.eventBus.dispatch('open_popup', e.type);
        }
      }
    });

    // Popup stuff
    each(document.querySelectorAll('[data-open-panel]'), function(el) {
      var element = document.getElementById(el.dataset.openPanel.slice(1));

      el.onclick = function() {
        my_addClass(element, 'open');
      };
    });

    each(document.querySelectorAll('[data-close-panel]'), function(el) {
      var element = document.getElementById(el.dataset.closePanel.slice(1));

      el.onclick = function() {
        my_removeClass(element, 'open');
      }
    });

    var setContainerHeight = function(containerEl) {
      console.log(containerEl);

      var bodyEl           = document.getElementsByClassName('squatch-body')[0];
      var titleEl          = document.getElementsByClassName('squatch-title')[0];
      var titleStyle       = getComputedStyle(titleEl);
      var panelEl          = document.getElementById('squatch-panel');
      var referralsEl      = document.getElementsByClassName('squatch-referrals')[0];
      var referralsTitleEl = document.getElementsByClassName('squatch-referrals-title')[0];

      var bodyHeight = bodyEl.offsetHeight;
      var bodyHeightWithoutTitle = bodyHeight - titleEl.offsetHeight - parseInt(titleStyle.marginTop) - parseInt(titleStyle.marginBottom) - titleEl.offsetTop;
      var panelHeight = panelEl ? panelEl.offsetHeight : 0;

      if (referralsEl && referralsEl.style.display !== 'none') {
        panelHeight -= referralsEl.offsetHeight;
      }

      if (referralsTitleEl && referralsTitleEl.style.display !== 'none') {
        panelHeight -= referralsTitleEl.offsetHeight;
      }

      containerEl.style.height = bodyHeight + panelHeight + "px";

      var stylesheet = document.createElement('style');
      stylesheet.type = 'text/css';

      var css = '#squatch-panel.open {' +
        '-webkit-transform: translate(0, -' + bodyHeightWithoutTitle + 'px);' +
        '-ms-transform: translate(0, -' + bodyHeightWithoutTitle + 'px);' +
        '-o-transform: translate(0, -' + bodyHeightWithoutTitle + 'px);' +
        'transform: translate(0, -' + bodyHeightWithoutTitle + 'px);' +
        '}' +
        'html.lt-ie9 #squatch-panel.open {' +
        'top: -' + bodyHeightWithoutTitle + 'px;' +
        '}';

      if (stylesheet.styleSheet){
        // IE
        stylesheet.styleSheet.cssText = css;
      } else {
        // W3C Standard
        stylesheet.appendChild(document.createTextNode(css));
      }

      document.querySelector('head').appendChild(stylesheet);
    };

    var containerEl = document.getElementsByClassName('squatch-container-popup')[0];

    if (containerEl) {
     window.onload = function() {
       setContainerHeight(containerEl);
     }

    }
  });

})();
<commit_msg>update cta<commit_after>(function() {
  'use strict';

  function listenToClick(element, name, fn) {
    if (document.addEventListener) {
      element.addEventListener(name, fn, false);
    } else {
      element.attachEvent((name === 'click') ? 'onclick' : name, fn);
    }
  }

  function handleClicks(elem, fn) {
    if (document.addEventListener) {
      // For all major browsers, except IE 8 and earlier
      elem.addEventListener("click", fn, false);
      elem.addEventListener("touchstart", fn, false);
    } else if (document.attachEvent) {
      // For IE 8 and earlier versions
      elem.attachEvent("onclick", fn, false);
      elem.attachEvent("touchstart", fn, false);
    }
  };

  function hasClass(el, className) {
    if (el.classList)
      return el.classList.contains(className)
    else
      return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'))
  }

  function my_addClass(el, className) {
    if (el.classList)
      el.classList.add(className)
    else if (!hasClass(el, className)) el.className += " " + className
  }

  function my_removeClass(el, className) {
    if (el.classList)
      el.classList.remove(className)
    else if (hasClass(el, className)) {
      var reg = new RegExp('(\\s|^)' + className + '(\\s|$)')
      el.className=el.className.replace(reg, ' ')
    }
  }

  function scrollTop(element, to, duration) {
    var start = element.scrollTop,
        change = to - start,
        currentTime = 0,
        increment = 20;

    var animateScroll = function(){
      currentTime += increment;
      var val = Math.easeInOutQuad(currentTime, start, change, duration);
      element.scrollTop = val;
      if(currentTime < duration) {
        setTimeout(animateScroll, increment);
      }
    };
    animateScroll();
  }

  //t = current time
  //b = start value
  //c = change in value
  //d = duration
  Math.easeInOutQuad = function (t, b, c, d) {
    t /= d/2;
    if (t < 1) return c/2*t*t + b;
    t--;
    return -c/2 * (t*(t-2) - 1) + b;
  }

  function each(o, cb, s){
    var n;
    if (!o){
      return 0;
    }
    s = !s ? o : s;
    if (o instanceof Array){
      // Indexed arrays, needed for Safari
      for (n=0; n<o.length; n++) {
        if (cb.call(s, o[n], n, o) === false){
          return 0;
        }
      }
    } else {
      // Hashtables
      for (n in o){
        if (o.hasOwnProperty(n)) {
          if (cb.call(s, o[n], n, o) === false){
            return 0;
          }
        }
      }
    }
    return 1;
  }

  domready(function() {

    var scrollElements = document.querySelectorAll('[data-scroll-element]');

    var inValidRange = function(offset, limit) {
      return offset >= 0 && offset < limit;
    };

    var setVisibility = function(element, nextOffset, limit) {
      if(inValidRange(nextOffset, limit)) {
        my_removeClass(element, 'disabled');
      } else {
        my_addClass(element, 'disabled');
      }
    };

    var setVisibilityAll = function(elements, newOffset) {
      var
        scrollElement,
        increment,
        nextOffset,
        limit;

      each(elements, function(el) {
        scrollElement = document.querySelector(el.dataset.scrollElement);
        increment  = parseInt(el.dataset.scrollIncrement);
        nextOffset = newOffset + increment;
        limit      = parseInt(scrollElement.dataset.scrollLimit);

        setVisibility(el, nextOffset, limit);
      });
    };

    var resetScroll = function(element) {
      element.scrollTop = 0;
      element.dataset.scrollOffset = 0;
    };

    each(document.querySelectorAll('[data-clipboard-target]'), function(el) {
      var clipboard = new Clipboard(el);
      var notification;

      var notify = function(clipboardNotification, notificationText) {
        notification = document.getElementById(clipboardNotification.slice(1));
        notification.textContent = notificationText;
        my_addClass(notification, 'in');
        setTimeout(function() {
          my_removeClass(notification, 'in');
        }, 1400);
      };

      var notifySuccess = function(e) {
        notify(e.trigger.dataset.clipboardNotification, "Copied!");
      };

      var notifyFailure = function(e) {
        //if the copy function failed the text should still be selected, so just ask the user to hit ctrl+c
        notify(e.trigger.dataset.clipboardNotification, "Press Ctrl+C to copy");
      };

      clipboard.on('success', notifySuccess);
      clipboard.on('error', notifyFailure);
      handleClicks(el, function(e) {
        if (window.parent.squatch.eventBus) {
          window.parent.squatch.eventBus.dispatch('copy_btn_clicked', e.type);
        }
      });
    });

    each(scrollElements, function(el) {
      var element = document.querySelector(el.dataset.scrollElement);
      var increment = parseInt(el.dataset.scrollIncrement);
      var limit     = parseInt(element.dataset.scrollLimit.valueOf());
      var offset    = parseInt(element.dataset.scrollOffset.valueOf());
      var newOffset;

      element.dataset.scrollLimit = limit;

      var nextOffset = offset + increment;

      setVisibility(el, nextOffset, limit);

      // Force IE to forget previous scroll top value
      resetScroll(element);

      listenToClick(el, 'click', function() {
        offset = parseInt(element.dataset.scrollOffset);

        newOffset = offset + increment;

        if (inValidRange(newOffset, limit)) {
          scrollTop(element, document.getElementById(newOffset).offsetTop, 400);
          element.dataset.scrollOffset = newOffset;

          setVisibilityAll(scrollElements, newOffset);
        }
      });
    });

    each(document.querySelectorAll('[data-moment]'), function(el) {
      var time = moment(parseInt(el.textContent));
      el.textContent = time.fromNow();
    });

    each(document.getElementsByClassName('squatch-header-close'), function(el) {
      handleClicks(el, function(e) {
        if (window.parent.squatch.eventBus) {
          window.parent.squatch.eventBus.dispatch('close_popup', e.type);
        }
      });
    });

    // CTA
    each(document.getElementsByClassName('cta-container'), function(el) {
      console.log('cta-container', el);

      el.onclick = function(e) {
        console.log('clicked');
        if (window.parent.squatch.eventBus) {
          window.parent.squatch.eventBus.dispatch('open_popup', e.type);
        }
      }
    });

    // Popup stuff
    each(document.querySelectorAll('[data-open-panel]'), function(el) {
      var element = document.getElementById(el.dataset.openPanel.slice(1));

      el.onclick = function() {
        my_addClass(element, 'open');
      };
    });

    each(document.querySelectorAll('[data-close-panel]'), function(el) {
      var element = document.getElementById(el.dataset.closePanel.slice(1));

      el.onclick = function() {
        my_removeClass(element, 'open');
      }
    });

    var setContainerHeight = function(containerEl) {
      var bodyEl           = document.getElementsByClassName('squatch-body')[0];
      var titleEl          = document.getElementsByClassName('squatch-title')[0];
      var titleStyle       = getComputedStyle(titleEl);
      var panelEl          = document.getElementById('squatch-panel');
      var referralsEl      = document.getElementsByClassName('squatch-referrals')[0];
      var referralsTitleEl = document.getElementsByClassName('squatch-referrals-title')[0];

      var bodyHeight = bodyEl.offsetHeight;
      var bodyHeightWithoutTitle = bodyHeight - titleEl.offsetHeight - parseInt(titleStyle.marginTop) - parseInt(titleStyle.marginBottom) - titleEl.offsetTop;
      var panelHeight = panelEl ? panelEl.offsetHeight : 0;

      if (referralsEl && referralsEl.style.display !== 'none') {
        panelHeight -= referralsEl.offsetHeight;
      }

      if (referralsTitleEl && referralsTitleEl.style.display !== 'none') {
        panelHeight -= referralsTitleEl.offsetHeight;
      }

      containerEl.style.height = bodyHeight + panelHeight + "px";

      var stylesheet = document.createElement('style');
      stylesheet.type = 'text/css';

      var css = '#squatch-panel.open {' +
        '-webkit-transform: translate(0, -' + bodyHeightWithoutTitle + 'px);' +
        '-ms-transform: translate(0, -' + bodyHeightWithoutTitle + 'px);' +
        '-o-transform: translate(0, -' + bodyHeightWithoutTitle + 'px);' +
        'transform: translate(0, -' + bodyHeightWithoutTitle + 'px);' +
        '}' +
        'html.lt-ie9 #squatch-panel.open {' +
        'top: -' + bodyHeightWithoutTitle + 'px;' +
        '}';

      if (stylesheet.styleSheet){
        // IE
        stylesheet.styleSheet.cssText = css;
      } else {
        // W3C Standard
        stylesheet.appendChild(document.createTextNode(css));
      }

      document.querySelector('head').appendChild(stylesheet);
    };

    var containerEl = document.getElementsByClassName('squatch-container-popup')[0];

    if (containerEl) {
     window.onload = function() {
       setContainerHeight(containerEl);
     }

    }
  });

})();
<|endoftext|>