text:
import Emm from '@mattermost/react-native-emm';
import {Alert, DeviceEventEmitter, Linking, Platform} from 'react-native';
import {Notifications} from 'react-native-notifications';

import {appEntry, pushNotificationEntry, upgradeEntry} from '@actions/remote/entry';
import {Screens, DeepLink, Events, Launch, PushNotification} from '@constants';
import DatabaseManager from '@database/manager';
import {getActiveServerUrl, getServerCredentials, removeServerCredentials} from '@init/credentials';
import {getThemeForCurrentTeam} from '@queries/servers/preference';
import {getCurrentUserId} from '@queries/servers/system';
import {queryMyTeams} from '@queries/servers/team';
import {goToScreen, resetToHome, resetToSelectServer, resetToTeams} from '@screens/navigation';
import EphemeralStore from '@store/ephemeral_store';
import {logInfo} from '@utils/log';
import {convertToNotificationData} from '@utils/notification';
import {parseDeepLink} from '@utils/url';

import type {DeepLinkChannel, DeepLinkDM, DeepLinkGM, DeepLinkPermalink, DeepLinkWithData, LaunchProps} from '@typings/launch';

const initialNotificationTypes = [PushNotification.NOTIFICATION_TYPE.MESSAGE, PushNotification.NOTIFICATION_TYPE.SESSION];

export const initialLaunch = async () => {
    const deepLinkUrl = await Linking.getInitialURL();
    if (deepLinkUrl) {
        launchAppFromDeepLink(deepLinkUrl, true);
        return;
    }

    const notification = await Notifications.getInitialNotification();
    let tapped = Platform.select({android: true, ios: false})!;
    if (Platform.OS === 'ios' && notification) {
        // when a notification is received on iOS, getInitialNotification, will return the notification
        // as the app will initialized cause we are using background fetch,
        // that does not necessarily mean that the app was opened cause of the notification was tapped.
        // Here we are going to dettermine if the notification still exists in NotificationCenter to determine if
        // the app was opened because of a tap or cause of the background fetch init
        const delivered = await Notifications.ios.getDeliveredNotifications();
        tapped = delivered.find((d) => (d as unknown as NotificationData).ack_id === notification?.payload.ack_id) == null;
    }
    if (initialNotificationTypes.includes(notification?.payload?.type) && tapped) {
        launchAppFromNotification(convertToNotificationData(notification!), true);
        return;
    }

    launchApp({launchType: Launch.Normal, coldStart: true});
};

const launchAppFromDeepLink = (deepLinkUrl: string, coldStart = false) => {
    const props = getLaunchPropsFromDeepLink(deepLinkUrl, coldStart);
    launchApp(props);
};

const launchAppFromNotification = async (notification: NotificationWithData, coldStart = false) => {
    const props = await getLaunchPropsFromNotification(notification, coldStart);
    launchApp(props);
};

const launchApp = async (props: LaunchProps, resetNavigation = true) => {
    let serverUrl: string | undefined;
    switch (props?.launchType) {
        case Launch.DeepLink:
            if (props.extra?.type !== DeepLink.Invalid) {
                const extra = props.extra as DeepLinkWithData;
                serverUrl = extra.data?.serverUrl;
            }
            break;
        case Launch.Notification: {
            serverUrl = props.serverUrl;
            const extra = props.extra as NotificationWithData;
            const sessionExpiredNotification = Boolean(props.serverUrl && extra.payload?.type === PushNotification.NOTIFICATION_TYPE.SESSION);
            if (sessionExpiredNotification) {
                DeviceEventEmitter.emit(Events.SESSION_EXPIRED, serverUrl);
                return '';
            }
            break;
        }
        default:
            serverUrl = await getActiveServerUrl();
            break;
    }

    if (props.launchError && !serverUrl) {
        serverUrl = await getActiveServerUrl();
    }

    if (serverUrl) {
        const credentials = await getServerCredentials(serverUrl);
        if (credentials) {
            const database = DatabaseManager.serverDatabases[serverUrl]?.database;
            let hasCurrentUser = false;
            if (database) {
                EphemeralStore.theme = await getThemeForCurrentTeam(database);
                const currentUserId = await getCurrentUserId(database);
                hasCurrentUser = Boolean(currentUserId);
            }

            let launchType = props.launchType;
            if (!hasCurrentUser) {
                // migrating from v1
                if (launchType === Launch.Normal) {
                    launchType = Launch.Upgrade;
                }

                const result = await upgradeEntry(serverUrl);
                if (result.error) {
                    Alert.alert(
                        'Error Upgrading',
                        `An error occurred while upgrading the app to the new version.\n\nDetails: ${result.error}\n\nThe app will now quit.`,
                        [{
                            text: 'OK',
                            onPress: async () => {
                                await DatabaseManager.destroyServerDatabase(serverUrl!);
                                await removeServerCredentials(serverUrl!);
                                Emm.exitApp();
                            },
                        }],
                    );
                    return '';
                }
            }

            return launchToHome({...props, launchType, serverUrl});
        }
    }

    return launchToServer(props, resetNavigation);
};

const launchToHome = async (props: LaunchProps) => {
    let openPushNotification = false;

    switch (props.launchType) {
        case Launch.DeepLink:
            // TODO:
            // deepLinkEntry({props.serverUrl, props.extra});
            break;
        case Launch.Notification: {
            const extra = props.extra as NotificationWithData;
            openPushNotification = Boolean(props.serverUrl && !props.launchError && extra.userInteraction && extra.payload?.channel_id && !extra.payload?.userInfo?.local);
            if (openPushNotification) {
                pushNotificationEntry(props.serverUrl!, extra);
            } else {
                appEntry(props.serverUrl!);
            }
            break;
        }
        case Launch.Normal:
            appEntry(props.serverUrl!);
            break;
    }

    let nTeams = 0;
    if (props.serverUrl) {
        const database = DatabaseManager.serverDatabases[props.serverUrl]?.database;
        if (database) {
            nTeams = await queryMyTeams(database).fetchCount();
        }
    }

    if (nTeams) {
        logInfo('Launch app in Home screen');
        return resetToHome(props);
    }

    logInfo('Launch app in Select Teams screen');
    return resetToTeams();
};

const launchToServer = (props: LaunchProps, resetNavigation: Boolean) => {
    if (resetNavigation) {
        return resetToSelectServer(props);
    }

    // This is being called for Deeplinks, but needs to be revisited when
    // the implementation of deep links is complete
    const title = '';
    return goToScreen(Screens.SERVER, title, {...props});
};

export const relaunchApp = (props: LaunchProps, resetNavigation = false) => {
    return launchApp(props, resetNavigation);
};

export const getLaunchPropsFromDeepLink = (deepLinkUrl: string, coldStart = false): LaunchProps => {
    const parsed = parseDeepLink(deepLinkUrl);
    const launchProps: LaunchProps = {
        launchType: Launch.DeepLink,
        coldStart,
    };

    switch (parsed.type) {
        case DeepLink.Invalid:
            launchProps.launchError = true;
            break;
        case DeepLink.Channel: {
            const parsedData = parsed.data as DeepLinkChannel;
            (launchProps.extra as DeepLinkWithData).data = parsedData;
            break;
        }
        case DeepLink.DirectMessage: {
            const parsedData = parsed.data as DeepLinkDM;
            (launchProps.extra as DeepLinkWithData).data = parsedData;
            break;
        }
        case DeepLink.GroupMessage: {
            const parsedData = parsed.data as DeepLinkGM;
            (launchProps.extra as DeepLinkWithData).data = parsedData;
            break;
        }
        case DeepLink.Permalink: {
            const parsedData = parsed.data as DeepLinkPermalink;
            (launchProps.extra as DeepLinkWithData).data = parsedData;
            break;
        }
    }

    return launchProps;
};

export const getLaunchPropsFromNotification = async (notification: NotificationWithData, coldStart = false): Promise<LaunchProps> => {
    const launchProps: LaunchProps = {
        launchType: Launch.Notification,
        coldStart,
    };

    const {payload} = notification;
    launchProps.extra = notification;

    if (payload?.server_url) {
        launchProps.serverUrl = payload.server_url;
    } else if (payload?.server_id) {
        const serverUrl = await DatabaseManager.getServerUrlFromIdentifier(payload.server_id);
        if (serverUrl) {
            launchProps.serverUrl = serverUrl;
        } else {
            launchProps.launchError = true;
        }
    } else {
        launchProps.launchError = true;
    }

    return launchProps;
};


text:
module ActiveRecord
	module Acts
		module Dag
			def self.included(base)
				base.extend(SingletonMethods)
			end
			module SingletonMethods
				#Sets up a model to act as dag links for models specified under the :for option
				def acts_as_dag_links(options = {})
					conf = {
						:ancestor_id_column => 'ancestor_id',
						:ancestor_type_column => 'ancestor_type',
						:descendant_id_column => 'descendant_id',
						:descendant_type_column => 'descendant_type',
						:direct_column => 'direct',
						:count_column => 'count',
						:polymorphic => false,
						:node_class_name => nil}
					conf.update(options)

					unless conf[:polymorphic]
						if conf[:node_class_name].nil?
							raise ActiveRecord::ActiveRecordError, 'Nonpolymorphic graphs need to specify :node_class_name with the recieving class like belong_to'
						end
					end

					write_inheritable_attribute :acts_as_dag_options, conf
					class_inheritable_reader :acts_as_dag_options

					extend Columns
					include Columns

					#access to _changed? and _was for (edge,count) if not default
					unless direct_column_name == 'direct'
						module_eval <<-"end_eval",__FILE__, __LINE__
						def direct_changed?
							self.#{direct_column_name}_changed?
						end
						def direct_was
							self.#{direct_column_name}_was
						end
						end_eval
					end

					unless count_column_name == 'count'
						module_eval <<-"end_eval",__FILE__, __LINE__
						def count_changed?
							self.#{count_column_name}_changed?
						end
						def count_was
							self.#{count_column_name}_was
						end
						end_eval
					end

					internal_columns = [ancestor_id_column_name,descendant_id_column_name]
					edge_class_name = self.to_s

					direct_column_name.intern
					count_column_name.intern

					#links to ancestor and descendant
					if acts_as_dag_polymorphic?
						extend PolyColumns
						include PolyColumns

						internal_columns << ancestor_type_column_name
						internal_columns << descendant_type_column_name

						belongs_to :ancestor, :polymorphic => true
						belongs_to :descendant, :polymorphic => true

						validates_presence_of ancestor_type_column_name, descendant_type_column_name
						validates_uniqueness_of ancestor_id_column_name, :scope => [ancestor_type_column_name,descendant_type_column_name,descendant_id_column_name]

						named_scope :with_ancestor, lambda {|ancestor| {:conditions => {ancestor_id_column_name => ancestor.id, ancestor_type_column_name => ancestor.class.to_s}}}
						named_scope :with_descendant, lambda {|descendant| {:conditions => {descendant_id_column_name => descendant.id, descendant_type_column_name => descendant.class.to_s}}}

						named_scope :with_ancestor_point, lambda {|point| {:conditions => {ancestor_id_column_name => point.id, ancestor_type_column_name => point.type}}}
						named_scope :with_descendant_point, lambda {|point| {:conditions => {descendant_id_column_name => point.id, descendant_type_column_name => point.type}}}

						extend PolyEdgeClassMethods
						include PolyEdgeClasses
						include PolyEdgeInstanceMethods
					else
						belongs_to :ancestor, :foreign_key => ancestor_id_column_name, :class_name => acts_as_dag_options[:node_class_name]
						belongs_to :descendant, :foreign_key => descendant_id_column_name, :class_name => acts_as_dag_options[:node_class_name]

						validates_uniqueness_of ancestor_id_column_name, :scope => [descendant_id_column_name]

						named_scope :with_ancestor, lambda {|ancestor| {:conditions => {ancestor_id_column_name => ancestor.id}}}
						named_scope :with_descendant, lambda {|descendant| {:conditions => {descendant_id_column_name => descendant.id}}}

						named_scope :with_ancestor_point, lambda {|point| {:conditions => {ancestor_id_column_name => point.id}}}
						named_scope :with_descendant_point, lambda {|point| {:conditions => {descendant_id_column_name => point.id}}}

						extend NonPolyEdgeClassMethods
						include NonPolyEdgeClasses
						include NonPolyEdgeInstanceMethods
					end

					named_scope :direct, :conditions => {:direct => true}
					named_scope :indirect, :conditions => {:direct => false}

					named_scope :ancestor_nodes, :joins => :ancestor
					named_scope :descendant_nodes, :joins => :descendant

					validates_presence_of ancestor_id_column_name, descendant_id_column_name
					validates_numericality_of ancestor_id_column_name, descendant_id_column_name

					extend EdgeClassMethods
					include EdgeInstanceMethods

					before_destroy :destroyable!, :perpetuate
					before_save :perpetuate
					before_validation_on_update :field_check, :fill_defaults
					before_validation_on_create :fill_defaults

					#internal fields
					code = 'def field_check ' + "\n"
					internal_columns.each do |column|
						code +=  "if " + column + "_changed? \n" + ' raise ActiveRecord::ActiveRecordError, "Column: '+column+' cannot be changed for an existing record it is immutable"' + "\n end \n"
					end
					code += 'end'
					module_eval code

					[count_column_name].each do |column|
						module_eval <<-"end_eval", __FILE__, __LINE__
						def #{column}=(x)
							raise ActiveRecord::ActiveRecordError, "Unauthorized assignment to #{column}: it's an internal field handled by acts_as_dag code."
						end
						end_eval
					end
				end
				def has_dag_links(options = {})
					conf = {
						:class_name => nil,
						:prefix => '',
						:ancestor_class_names => [],
						:descendant_class_names => []
					}
					conf.update(options)

					#check that class_name is filled
					if conf[:link_class_name].nil?
						raise ActiveRecord::ActiveRecordError, "has_dag must be provided with :link_class_name option"
					end

					#add trailing '_' to prefix
					unless conf[:prefix] == ''
						conf[:prefix] += '_'
					end

					prefix = conf[:prefix]
					dag_link_class_name = conf[:link_class_name]
					dag_link_class = conf[:link_class_name].constantize

					if dag_link_class.acts_as_dag_polymorphic?
						self.class_eval <<-EOL
              has_many :#{prefix}links_as_ancestor, :as => :ancestor, :class_name => '#{dag_link_class_name}'
              has_many :#{prefix}links_as_descendant, :as => :descendant, :class_name => '#{dag_link_class_name}'

              has_many :#{prefix}links_as_parent, :as => :ancestor, :class_name => '#{dag_link_class_name}', :conditions => {'#{dag_link_class.direct_column_name}' => true}
              has_many :#{prefix}links_as_child, :as => :descendant, :class_name => '#{dag_link_class_name}', :conditions => {'#{dag_link_class.direct_column_name}' => true}

            EOL

						ancestor_table_names = []
						parent_table_names = []
						conf[:ancestor_class_names].each do |class_name|
							table_name = class_name.tableize
							self.class_eval <<-EOL2
                has_many :#{prefix}links_as_descendant_for_#{table_name}, :as => :descendant, :class_name => '#{dag_link_class_name}', :conditions => {'#{dag_link_class.ancestor_type_column_name}' => '#{class_name}'}
                has_many :#{prefix}ancestor_#{table_name}, :through => :#{prefix}links_as_descendant_for_#{table_name}, :source => :ancestor, :source_type => '#{class_name}'
                has_many :#{prefix}links_as_child_for_#{table_name}, :as => :descendant, :class_name => '#{dag_link_class_name}', :conditions => {'#{dag_link_class.ancestor_type_column_name}' => '#{class_name}','#{dag_link_class.direct_column_name}' => true}
                has_many :#{prefix}parent_#{table_name}, :through => :#{prefix}links_as_child_for_#{table_name}, :source => :ancestor, :source_type => '#{class_name}'

              	def #{prefix}root_for_#{table_name}?
									return self.links_as_descendant_for_#{table_name}.empty?
            		end
              EOL2
							ancestor_table_names << (prefix+'ancestor_'+table_name)
							parent_table_names << (prefix+'parent_'+table_name)
							unless conf[:descendant_class_names].include?(class_name)
								#this apparently is only one way is we can create some aliases making things easier
								self.class_eval "has_many :#{prefix}#{table_name}, :through => :#{prefix}links_as_descendant_for_#{table_name}, :source => :ancestor, :source_type => '#{class_name}'"
							end
						end

						unless conf[:ancestor_class_names].empty?
							self.class_eval <<-EOL25
								def #{prefix}ancestors
									return #{ancestor_table_names.join(' + ')}
								end
								def #{prefix}parents
									return #{parent_table_names.join(' + ')}
								end
							EOL25
						else
							self.class_eval <<-EOL26
								def #{prefix}ancestors
									a = []
									#{prefix}links_as_descendant.each do |link|
										a << link.ancestor
									end
									return a
								end
								def #{prefix}parents
									a = []
									#{prefix}links_as_child.each do |link|
										a << link.ancestor
									end
									return a
								end
							EOL26
						end

						descendant_table_names = []
						child_table_names = []
						conf[:descendant_class_names].each do |class_name|
							table_name = class_name.tableize
							self.class_eval <<-EOL3
                has_many :#{prefix}links_as_ancestor_for_#{table_name}, :as => :ancestor, :class_name => '#{dag_link_class_name}', :conditions => {'#{dag_link_class.descendant_type_column_name}' => '#{class_name}'}
                has_many :#{prefix}descendant_#{table_name}, :through => :#{prefix}links_as_ancestor_for_#{table_name}, :source => :descendant, :source_type => '#{class_name}'

                has_many :#{prefix}links_as_parent_for_#{table_name}, :as => :ancestor, :class_name => '#{dag_link_class_name}', :conditions => {'#{dag_link_class.descendant_type_column_name}' => '#{class_name}','#{dag_link_class.direct_column_name}' => true}
                has_many :#{prefix}child_#{table_name}, :through => :#{prefix}links_as_parent_for_#{table_name}, :source => :descendant, :source_type => '#{class_name}'

								def #{prefix}leaf_for_#{table_name}?
                	return self.links_as_ancestor_for_#{table_name}.empty?
              	end
              EOL3
							descendant_table_names << (prefix+'descendant_'+table_name)
							child_table_names << (prefix+'child_'+table_name)
							unless conf[:ancestor_class_names].include?(class_name)
								self.class_eval "has_many :#{prefix}#{table_name}, :through => :#{prefix}links_as_ancestor_for_#{table_name}, :source => :descendant, :source_type => '#{class_name}'"
							end
						end

						unless conf[:descendant_class_names].empty?
							self.class_eval <<-EOL35
								def #{prefix}descendants
									return #{descendant_table_names.join(' + ')}
								end
								def #{prefix}children
									return #{child_table_names.join(' + ')}
								end
							EOL35
						else
							self.class_eval <<-EOL36
								def #{prefix}descendants
									d = []
									#{prefix}links_as_ancestor.each do |link|
										d << link.descendant
									end
									return d
								end
								def #{prefix}children
									d = []
									#{prefix}links_as_parent.each do |link|
										d << link.descendant
									end
									return d
								end
							EOL36
						end
					else
						self.class_eval <<-EOL4
              has_many :#{prefix}links_as_ancestor, :foreign_key => '#{dag_link_class.ancestor_id_column_name}', :class_name => '#{dag_link_class_name}'
              has_many :#{prefix}links_as_descendant, :foreign_key => '#{dag_link_class.descendant_id_column_name}', :class_name => '#{dag_link_class_name}'

              has_many :#{prefix}ancestors, :through => :#{prefix}links_as_descendant, :source => :ancestor
              has_many :#{prefix}descendants, :through => :#{prefix}links_as_ancestor, :source => :descendant

              has_many :#{prefix}links_as_parent, :foreign_key => '#{dag_link_class.ancestor_id_column_name}', :class_name => '#{dag_link_class_name}', :conditions => {'#{dag_link_class.direct_column_name}' => true}
              has_many :#{prefix}links_as_child, :foreign_key => '#{dag_link_class.descendant_id_column_name}', :class_name => '#{dag_link_class_name}', :conditions => {'#{dag_link_class.direct_column_name}' => true}

              has_many :#{prefix}parents, :through => :#{prefix}links_as_child, :source => :ancestor
              has_many :#{prefix}children, :through => :#{prefix}links_as_parent, :source => :descendant

            EOL4
					end
					self.class_eval <<-EOL5
            def #{prefix}leaf?
              return self.#{prefix}links_as_ancestor.empty?
						end
						def #{prefix}root?
							return self.#{prefix}links_as_descendant.empty?
						end
					EOL5
				end
			end

			#Methods that show the columns for polymorphic DAGs
			module PolyColumns
				def ancestor_type_column_name
					acts_as_dag_options[:ancestor_type_column]
				end

				def descendant_type_column_name
					acts_as_dag_options[:descendant_type_column]
				end
			end

			#Methods that show columns
			module Columns
				def ancestor_id_column_name
					acts_as_dag_options[:ancestor_id_column]
				end

				def descendant_id_column_name
					acts_as_dag_options[:descendant_id_column]
				end

				def direct_column_name
					acts_as_dag_options[:direct_column]
				end

				def count_column_name
					acts_as_dag_options[:count_column]
				end

				def acts_as_dag_polymorphic?
					acts_as_dag_options[:polymorphic]
				end
			end

			#Contains class methods that extend the link model for polymorphic DAGs
			module PolyEdgeClassMethods
				#Builds a hash that describes a link from a source and a sink
				def conditions_for(source,sink)
					{
						ancestor_id_column_name => source.id,
						ancestor_type_column_name => source.type,
						descendant_id_column_name => sink.id,
						descendant_type_column_name => sink.type
					}
				end
			end
			#Contains nested classes in the link model for polymorphic DAGs
			module PolyEdgeClasses
				#Encapsulates the necessary information about a graph node
				class EndPoint
					#Does the endpoint match a model or another endpoint
					def matches?(other)
						return (self.id == other.id) && (self.type == other.type) if other.is_a?(EndPoint)
						return (self.id == other.id) && (self.type == other.class.to_s)
					end

					#Factory Construction method that creates an EndPoint instance from a model
					def self.from_resource(resource)
						self.new(resource.id,resource.class.to_s)
					end

					#Factory Construction method that creates an EndPoint instance from a model if necessary
					def self.from(obj)
						return obj if obj.kind_of?(EndPoint)
						return self.from_resource(obj)
					end

					#Initializes the EndPoint instance with an id and type
					def initialize(id,type)
						@id = id
						@type = type
					end

					attr_reader :id, :type
				end

				#Encapsulates information about the source of a link
				class Source < EndPoint
					#Factory Construction method that generates a source from a link
					def self.from_edge(edge)
						self.new(edge.ancestor_id,edge.ancestor_type)
					end
				end

				#Encapsulates information about the sink (destination) of a link
				class Sink < EndPoint
					#Factory Construction method that generates a sink from a link
					def self.from_edge(edge)
						self.new(edge.descendant_id,edge.descendant_type)
					end
				end
			end

			#Contains class methods that extend the link model for a nonpolymorphic DAG
			module NonPolyEdgeClassMethods
				#Builds a hash that describes a link from a source and a sink
				def conditions_for(source,sink)
					{
						ancestor_id_column_name => source.id,
						descendant_id_column_name => sink.id
					}
				end
			end
			#Contains nested classes in the link model for a nonpolymorphic DAG
			module NonPolyEdgeClasses
				#Encapsulates the necessary information about a graph node
				class EndPoint
					#Does an endpoint match another endpoint or model instance
					def matches?(other)
						return (self.id == other.id)
					end

					#Factory Construction method that creates an endpoint from a model
					def self.from_resource(resource)
						self.new(resource.id)
					end

					#Factory Construction method that creates an endpoint from a model if necessary
					def self.from(obj)
						return obj if obj.kind_of?(EndPoint)
						return self.from_resource(obj)
					end

					#Initializes an endpoint based on an Id
					def initialize(id)
						@id = id
					end

					attr_reader :id
				end

				#Encapsulates information about the source of a link
				class Source < EndPoint
					#Factory Construction method creates a source instance from a link
					def self.from_edge(edge)
						return self.new(edge.ancestor_id)
					end
				end
				#Encapsulates information about the sink of a link
				class Sink < EndPoint
					#Factory Construction method creates a sink instance from a link
					def self.from_edge(edge)
						return self.new(edge.descendant_id)
					end
				end
			end

			#Class methods that extend the link model for both polymorphic and nonpolymorphic graphs
			module EdgeClassMethods

				#Returns a new edge between two points
				def build_edge(ancestor,descendant)
					source = self::EndPoint.from(ancestor)
					sink = self::EndPoint.from(descendant)
					conditions = self.conditions_for(source,sink)
					path = self.new(conditions)
					path.make_direct
					return path
				end

				#Finds an edge between two points, Must be direct
				def find_edge(ancestor,descendant)
					source = self::EndPoint.from(ancestor)
					sink = self::EndPoint.from(descendant)
					edge = self.find(:first,:conditions => self.conditions_for(source,sink).merge!({direct_column_name => true}))
					return edge
				end

				#Finds a link between two points
				def find_link(ancestor,descendant)
					source = self::EndPoint.from(ancestor)
					sink = self::EndPoint.from(descendant)
					link = self.find(:first,:conditions => self.conditions_for(source,sink))
					return link
				end

				#Finds or builds an edge between two points
				def find_or_build_edge(ancestor,descendant)
					edge = self.find_edge(ancestor,descendant)
					return edge unless edge.nil?
					return build_edge(ancestor,descendant)
				end

				#Creates an edge between two points using save
				def create_edge(ancestor,descendant)
					link = self.find_link(ancestor,descendant)
					if link.nil?
						edge = self.build_edge(ancestor,descendant)
						return edge.save
					else
						link.make_direct
						return link.save
					end
				end

				#Creates an edge between two points using save! Returns created edge
				def create_edge!(ancestor,descendant)
					link = self.find_link(ancestor,descendant)
					if link.nil?
						edge = self.build_edge(ancestor,descendant)
						edge.save!
						return edge
					else
						link.make_direct
						link.save!
						return link
					end
				end

				#Alias for create_edge
				def connect(ancestor,descendant)
					return self.create_edge(ancestor,descendant)
				end

				#Alias for create_edge!
				def connect!(ancestor,descendant)
					return self.create_edge!(ancestor,descendant)
				end

				#Determines if a link exists between two points
				def connected?(ancestor,descendant)
					return !self.find_link(ancestor,descendant).nil?
				end

				#Finds the longest path between ancestor and descendant returning as an array
				def longest_path_between(ancestor,descendant,path=[])
					longest = []
					ancestor.children.each do |child|
						if child == descendent
							temp = path.clone
							temp << child
							if temp.length > longest.length
								longest = temp
							end
						elsif self.connected?(child,descendant)
							temp = path.clone
							temp << child
							temp = self.longest_path_between(child,descendant,temp)
							if temp.length > longest.length
								longest = temp
							end
						end
					end
					return longest
				end

				#Determines if an edge exists between two points
				def edge?(ancestor,descendant)
					return !self.find_edge(ancestor,descendant).nil?
				end

				#Alias for edge
				def direct?(ancestor,descendant)
					return self.edge?(ancestor,descendant)
				end
			end

			#Instance methods included into link model for a polymorphic DAG
			module PolyEdgeInstanceMethods
				def ancestor_type
					return self[ancestor_type_column_name]
				end

				def descendant_type
					return self[descendant_type_column_name]
				end
			end

			#Instance methods included into the link model for a nonpolymorphic DAG
			module NonPolyEdgeInstanceMethods
			end

			#Instance methods included into the link model for polymorphic and nonpolymorphic DAGs
			module EdgeInstanceMethods

				attr_accessor :do_not_perpetuate

				#Validations on model instance creation. Ensures no duplicate links, no cycles, and correct count and direct attributes
				def validate_on_create
					#make sure no duplicates
					if self.class.find_link(self.source,self.sink)
						self.errors.add_to_base('Link already exists between these points')
					end
					#make sure no long cycles
					if self.class.find_link(self.sink,self.source)
						self.errors.add_to_base('Link already exists in the opposite direction')
					end
					#make sure no short cycles
					if self.sink.matches?(self.source)
						self.errors.add_to_base('Link must start and end in different places')
					end
					#make sure not impossible
					if self.direct?
						if self.count != 0
							self.errors.add_to_base('Cannot create a direct link with a count other than 0')
						end
					else
						if self.count < 1
							self.errors.add_to_base('Cannot create an indirect link with a count less than 1')
						end
					end
				end

				#Validations on update. Makes sure that something changed, that not making a lonely link indirect, and count is correct.
				def validate_on_update
					unless self.changed?
						self.errors.add_to_base('No changes')
					end
					if direct_changed?
						if count_changed?
							self.errors.add_to_base('Do not manually change the count value')
						end
						if !self.direct?
							if self.count == 1
								self.errors.add_to_base('Cannot make a direct link with count 1 indirect')
							end
						end
					end
				end

				#Fill default direct and count values if necessary. In place of after_initialize method
				def fill_defaults
					self[direct_column_name] = true if self[direct_column_name].nil?
					self[count_column_name] = 0 if self[count_column_name].nil?
				end

				#Whether the edge can be destroyed
				def destroyable?
				(self.count == 0) || (self.direct? && self.count == 1)
				end

				#Raises an exception if the edge is not destroyable. Otherwise makes the edge indirect before destruction to cleanup graph.
				def destroyable!
					raise ActiveRecord::ActiveRecordError, 'Cannot destroy this edge' unless destroyable?
					#this triggers rewiring on destruction via perpetuate
					if self.direct?
						self[direct_column_name] = false
					end
					return true
				end

				#Analyzes the changes in a model instance and rewires as necessary.
				def perpetuate
					#flag set by links that were modified in association
					return true if self.do_not_perpetuate

					#if edge changed this was manually altered
					if direct_changed?
						if self.direct?
							self[count_column_name] += 1
						else
							self[count_column_name] -= 1
						end
						self.wiring
					end
				end

				#Id of the ancestor
				def ancestor_id
					return self[ancestor_id_column_name]
				end

				#Id of the descendant
				def descendant_id
					return self[descendant_id_column_name]
				end

				#Count of the edge, ie the edge exists in X ways
				def count
					return self[count_column_name]
				end

				#Changes the count of the edge. DO NOT CALL THIS OUTSIDE THE PLUGIN
				def internal_count=(val)
					self[count_column_name] = val
				end

				#Whether the link is direct, ie manually created
				def direct?
					return self[direct_column_name]
				end

				#Whether the link is an edge?
				def edge?
					return self[direct_column_name]
				end

				#Makes the link direct, ie an edge
				def make_direct
					self[direct_column_name] = true
				end

				#Makes an edge indirect, ie a link.
				def make_indirect
					self[direct_column_name] = false
				end

				#Source of the edge, creates if necessary
				def source
					@source = self.class::Source.from_edge(self) if @source.nil?
					return @source
				end

				#Sink (destination) of the edge, creates if necessary
				def sink
					@sink = self.class::Sink.from_edge(self) if @sink.nil?
					return @sink
				end

				#All links that end at the source
				def links_to_source
					self.class.with_descendant_point(self.source)
				end

				#all links that start from the sink
				def links_from_sink
					self.class.with_ancestor_point(self.sink)
				end

				protected

				#Changes on a wire based on the count (destroy! or save!) (should not be called outside this plugin)
				def push_associated_modification!(edge)
					raise ActiveRecord::ActiveRecordError, 'Cannot modify ourself in this way' if edge == self
					edge.do_not_perpetuate = true
					if edge.count == 0
						edge.destroy!
					else
						edge.save!
					end
				end

				#Updates the wiring of edges that dependent on the current one
				def rewire_crossing(above_leg,below_leg)
					if above_leg.count_changed?
						was = above_leg.count_was
						was = 0 if was.nil?
						above_leg_count = above_leg.count - was
						if below_leg.count_changed?
							raise ActiveRecord::ActiveRecordError, 'ERROR: both legs cannot 0 normal count change'
						else
							below_leg_count = below_leg.count
						end
					else
						above_leg_count = above_leg.count
						if below_leg.count_changed?
							was = below_leg.count_was
							was = 0 if was.nil?
							below_leg_count = below_leg.count - was
						else
							raise ActiveRecord::ActiveRecordError, 'ERROR: both legs cannot have count changes'
						end
					end
					count = above_leg_count * below_leg_count
					source = above_leg.source
					sink = below_leg.sink
					bridging_leg = self.class.find_link(source,sink)
					if bridging_leg.nil?
						bridging_leg = self.class.new(self.class.conditions_for(source,sink))
						bridging_leg.make_indirect
						bridging_leg.internal_count = 0
					end
					bridging_leg.internal_count = bridging_leg.count + count
					return bridging_leg
				end

				#Find the edges that need to be updated
				def wiring
					source = self.source
					sink = self.sink
					above_sources = []
					self.links_to_source.each do |edge|
						above_sources << edge.source
					end
					below_sinks = []
					self.links_from_sink.each do |edge|
						below_sinks << edge.sink
					end
					above_bridging_legs = []
					#everything above me tied to my sink
					above_sources.each do |above_source|
						above_leg = self.class.find_link(above_source,source)
						above_bridging_leg = self.rewire_crossing(above_leg,self)
						above_bridging_legs << above_bridging_leg unless above_bridging_leg.nil?
					end

					#everything beneath me tied to my source
					below_sinks.each do |below_sink|
						below_leg = self.class.find_link(sink,below_sink)
						below_bridging_leg = self.rewire_crossing(self,below_leg)
						self.push_associated_modification!(below_bridging_leg)
						above_bridging_legs.each do |above_bridging_leg|
							long_leg = self.rewire_crossing(above_bridging_leg,below_leg)
							self.push_associated_modification!(long_leg)
						end
					end
					above_bridging_legs.each do |above_bridging_leg|
						self.push_associated_modification!(above_bridging_leg)
					end
				end
			end
		end
	end
end

redpajama_set_name: RedPajamaGithub


text:
import six
import rfc822
import logging
from time import mktime
from datetime import datetime

from ExtractMsg import Message
from olefile import isOleFile
from flanker.addresslib import address

from aleph.ingest import ingest_file
from aleph.ingest.text import TextIngestor
from aleph.ingest.document import DocumentIngestor
from aleph.text import string_value
from aleph.util import make_tempfile, remove_tempfile

log = logging.getLogger(__name__)

class OutlookMsgIngestor(TextIngestor):
    MIME_TYPES = []
    EXTENSIONS = ['msg']
    BASE_SCORE = 10

    def ingest_attachment(self, attachment, meta):
        try:
            if attachment.data is None:
                log.warning("Attachment is empty [%r]: %s",
                            meta, attachment.longFilename)
                return
            out_path = make_tempfile()
            with open(out_path, 'w') as fh:
                fh.write(attachment.data)
            child = meta.make_child()
            child.file_name = string_value(attachment.longFilename)
            ingest_file(self.collection_id, child, out_path, move=True)
            remove_tempfile(out_path)
        except Exception as ex:
            log.exception(ex)

    def parse_headers(self, header, meta):
        meta.title = header.get('Subject')

        if header.get('Message-Id'):
            meta.foreign_id = string_value(header.get('Message-Id'))

        if header.get('From'):
            addr = address.parse(header.get('From'))
            if addr is not None:
                meta.author = addr.to_unicode()
                meta.add_email(addr.address)

        for hdr in ['To', 'CC', 'BCC']:
            if header.get(hdr):
                for addr in address.parse_list(header.get(hdr)):
                    meta.add_email(addr.address)

        date = header.get('Date')
        date = rfc822.parsedate(date)
        if date is not None:
            dt = datetime.fromtimestamp(mktime(date))
            meta.add_date(dt)

        meta.headers = dict([(k, string_value(v)) for k, v in
                             header.items()])
        return meta

    def ingest(self, meta, local_path):
        message = Message(local_path)
        if message.header is not None:
            meta = self.parse_headers(message.header, meta)

        for attachment in message.attachments:
            self.ingest_attachment(attachment, meta)

        if message.body is not None:
            out_path = make_tempfile(suffix='txt')
            with open(out_path, 'w') as fh:
                # TODO: figure out if this is really IMAP UTF-7
                body = string_value(message.body)
                fh.write(body.encode('utf-8'))
            ing = DocumentIngestor(self.collection_id)
            ing.ingest(meta, out_path)
            remove_tempfile(out_path)

    @classmethod
    def match(cls, meta, local_path):
        if isOleFile(local_path):
            if meta.mime_type in cls.MIME_TYPES:
                return cls.BASE_SCORE
            if meta.extension in cls.EXTENSIONS:
                return cls.BASE_SCORE
        return -1


text:
%%%%\%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Introduction aux Systèmes d'exploitation  %%
%%   * Historique                            %%
%%   * Principes fondamentaux                %%
%%   * Grandes classes de systèmes           %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\title{Systèmes d'exploitation, 2ème année}
\subtitle{Primitives Execs}

\author{Yves \textsc{Stadler}}\institute{Université Paul Verlaine - Metz}

\date{\today}

\begin{document}

%%
% Page de Titre
%%
\begin{frame}
\titlepage
\end{frame}

\def\sectitle{Agenda}
\section{\sectitle}
\def\subsectitle{Plan du cours}
\subsection{\subsectitle}

\begin{frame}{\sectitle}
\begin{block}{\subsectitle}
\begin{itemize}
\item Concept
\item Fonctions
\item Réalisation
\end{itemize}
\end{block}
\end{frame}

\def\subsectitle{}
\subsection{\subsectitle}

\def\sectitle{Exec}
\section{\sectitle}
\begin{frame}{\sectitle}
\def\subsectitle{Notion}
\subsection{\subsectitle}
\begin{block}{\subsectitle}
\begin{itemize}
\item Lancer un programme existant depuis un autre programme
\item Idée: remplacer l'image mémoire du processus par une autre
\item Les primitives exec vont nous permettre de faire ça.
\end{itemize}
\end{block}

\def\subsectitle{Remarque}
\subsection{\subsectitle}
\begin{alertblock}{\subsectitle}
\begin{itemize}
\item Attention, lorsque l'on appel une primitive exec celle-ci ne se terminera
pas.
\item Un processus qui appel une primitive exec ne changera pas d'identité.
\end{itemize}

\end{alertblock}

\end{frame}

\begin{frame}[containsverbatim]{\sectitle}
\def\subsectitle{Parmètres}
\subsection{\subsectitle}
\begin{block}{\subsectitle}
\begin{itemize}
    \item Un programme
    \item Des paramètres
    \item Des variables d'environnement.
\end{itemize}
\end{block}

\def\subsectitle{Example}
\subsection{\subsectitle}
\begin{exampleblock}{\subsectitle}
\begin{verbatim}{\subsectitle}
int main(int argc, char * argv[], char * arge[]);
\end{verbatim}
\end{exampleblock}
\end{frame}

\begin{frame}[containsverbatim]{\sectitle}
\def\subsectitle{man exec}
\subsection{\subsectitle}
\begin{block}{\subsectitle}
\begin{verbatim}
NAME
       execl, execlp, execle, execv, execvp - execute a file

SYNOPSIS
       #include <unistd.h>

       extern char **environ;

       int execl(const char *path, const char *arg, ...);
       int execlp(const char *file, const char *arg, ...);
       int execle(const char *path, const char *arg,
                  ..., char * const envp[]);
       int execv(const char *path, char *const argv[]);
       int execvp(const char *file, char *const argv[]);
\end{verbatim}
\end{block}
\end{frame}

\begin{frame}{\sectitle}
\def\subsectitle{Différences}
\subsection{\subsectitle}
\begin{block}{\subsectitle}
\begin{itemize}
    \item Recherche du programme :
    \begin{itemize}
        \item vide: répertoire en cours (execl, execv, execle)
        \item p : path (execlp, execvp)
    \end{itemize}
    \item Arguments du programme :
    \begin{itemize}
        \item vide: tableau (terminé par NULL)
        \item l : liste explicite (terminée par NULL)
    \end{itemize}
    \item Utiliser:
    \begin{itemize}
        \item vide: environnement courant
        \item e : environnement sous forme de tableau (terminé par NULL)
    \end{itemize}
\end{itemize}
\end{block}
\end{frame}

\begin{frame}{\sectitle}
\def\subsectitle{Fonctionnement}
\subsection{\subsectitle}
\begin{block}{\subsectitle}
\begin{itemize}
    \item Rechercher le fichier pointer par arg1
    \item Vérifier que le fichier est exécutable (permissions)
    \item Vérifier dans l'entête que le fichier peut être chargé
    \item Copier les paramètres de l'exec courant dans l'espace système
    \item Détacher toutes les régions du programme
    \item Allouer de nouvelles régions
    \item Attacher les nouvelles régions
    \item Charger la région en mémoire
    \item Copier les paramètres de l'exec dans la pile utilisateur.
\end{itemize}
\end{block}
\end{frame}

\def\sectitle{}
\section{\sectitle}
\begin{frame}{\sectitle}
\def\subsectitle{Ne pas oublier}
\subsection{\subsectitle}
\begin{block}{\subsectitle}
\begin{itemize}
    \item Sauf si il échoue à se lancer, on ne revient pas d'un exec
    \item Tout le code écrit après un exec qui a réussi n'existe plus!
    (écrasement)
\end{itemize}
\end{block}

\def\subsectitle{Contrôle}
\subsection{\subsectitle}
\begin{block}{\subsectitle}
\begin{itemize}
    \item \texttt{pid\_t wait(int *status);}
    \item \texttt{pid\_t waitpid(pid\_t pid, int *status, int options);}
    \item \texttt{ waitpid(-1, \&status, 0);}
    \item Comment exploiter la variable status.
\end{itemize}
\end{block}

\end{frame}

\def\sectitle{Fin de processus}
\section{\sectitle}
\begin{frame}{\sectitle}
\begin{block}{\subsectitle}
\def\subsectitle{Mort du processus}
\subsection{\subsectitle}
\begin{itemize}
    \item Fonction de tests
    \item WIFEXITED(status) : indique si un processus s'est terminé correctement
    \item WEXITSTATUS(status): code d'erreur retourné par le fils (exit/return)
    \item WIFSIGNALED(status): vrai si fils terminé par un signal
    \item WTERMSIG(satus): renvoi le numéro du signal qui a terminé le fils
\end{itemize}
\end{block}
\end{frame}

\begin{frame}{\sectitle}
\def\subsectitle{Communication intrasèque}
\subsection{\subsectitle}
\begin{block}{\subsectitle}
\begin{itemize}
    \item Comment communiquer avec les fils ?
    \item Redirection d'entrée standard et de sortie standard (dup)
    \item Utilisation des pipes nommés
    \item Utilisation de popen (pipe + fork + shell)
\end{itemize}
\end{block}
\end{frame}

\def\sectitle{Divers}
\section{\sectitle}
\begin{frame}{\sectitle}
\def\subsectitle{Divers}
\subsection{\subsectitle}
\begin{block}{\subsectitle}
\begin{itemize}
    \item \texttt{int system(const char *command);} si on veut juste exécuter
    une commande.
    \item \texttt{vfork}: système dédié nécessitant performance -> père bloqué
    tant que le fils existe et n'a pas fait un \texttt{exevce}
    \item Dans le cas du vfork, il y a un partage de mémoire temporaire. A
    utiliser avec extrème précaution.
    \item Si on veut travailler avec des mémoires partagées, il existe
    \texttt{clone}
    \item Clone est utilisé pour créer des threads.
\end{itemize}
\end{block}
\end{frame}

\end{document}


text:
function DelegationManager(userSettings) {
    'use strict';
    /*jslint browser: true*/

    var currentArguments,
        delayToDelegateEventChange = -1,
        timeout = null,
        settings = {
                     fps: 10,
                     latencyToEndEvent: 200
                   },
        delegate = {
                     eventDidStart: function (parameterContainer) { return; },
                     eventDidChange: function (parameterContainer) { return; },
                     eventDidEnd: function (parameterContainer) { return; }
                   };

    function init() {
        var property;

        //overwrite those settings that where set by the user
        for (property in userSettings) {
            if (userSettings.hasOwnProperty(property) && settings.hasOwnProperty(property)) {
                if (typeof settings[property] === typeof userSettings[property]) {
                    settings[property] = userSettings[property];
                }
            }
        }

        delayToDelegateEventChange = 1000 / settings.fps;
    }

    init();

    function eventDidChange() {
        if (timeout) {
            delegate.eventDidChange.apply(undefined, currentArguments);

            setTimeout(function () {
                eventDidChange();
            }, delayToDelegateEventChange);
        }
    }

    function eventDidTick() {
        var didStart = false;
        if (!timeout) {
            didStart = true;
        }

        currentArguments = arguments;

        clearTimeout(timeout);
        timeout = setTimeout(function () {
            delegate.eventDidEnd.apply(undefined, currentArguments);
            timeout = null;
        }, settings.latencyToEndEvent);

        if (didStart) {
            delegate.eventDidStart.apply(undefined, arguments);
            eventDidChange.apply(undefined, arguments);
        }
    }

    return {
        tick: function () {
            eventDidTick.apply(undefined, arguments);
        },
        setEventDidStart: function (eds) {
            if (typeof eds === typeof delegate.eventDidStart) {
                delegate.eventDidStart = eds;
            }
        },
        setEventDidChange: function (edc) {
            if (typeof edc === typeof delegate.eventDidChange) {
                delegate.eventDidChange = edc;
            }
        },
        setEventDidEnd: function (ede) {
            if (typeof ede === typeof delegate.eventDidEnd) {
                delegate.eventDidEnd = ede;
            }
        }
    };
}


text:
class DownloadShelfView;

namespace content {
class WebContents;
}  // namespace content

namespace gfx {
class Canvas;
class Point;
class Rect;
}  // namespace gfx

namespace views {
class Button;
class ImageButton;
class Label;
class MdTextButton;
class StyledLabel;
}  // namespace views

// A view that implements one download on the Download shelf. Each
// DownloadItemView contains an application icon, a text label indicating the
// download's file name, a text label indicating the download's status (such as
// the number of bytes downloaded so far), and a button for canceling an
// in-progress download, or opening the completed download.
//
// The DownloadItemView lives in the Browser, and has a corresponding
// DownloadController that receives / writes data which lives in the Renderer.
class DownloadItemView : public views::View,
                         public views::ContextMenuController,
                         public DownloadUIModel::Observer,
                         public views::AnimationDelegateViews {
 public:
  METADATA_HEADER(DownloadItemView);

  DownloadItemView(DownloadUIModel::DownloadUIModelPtr model,
                   DownloadShelfView* shelf,
                   views::View* accessible_alert);
  DownloadItemView(const DownloadItemView&) = delete;
  DownloadItemView& operator=(const DownloadItemView&) = delete;
  ~DownloadItemView() override;

  // views::View:
  void AddedToWidget() override;
  void Layout() override;
  bool OnMouseDragged(const ui::MouseEvent& event) override;
  void OnMouseCaptureLost() override;
  std::u16string GetTooltipText(const gfx::Point& p) const override;
  void GetAccessibleNodeData(ui::AXNodeData* node_data) override;

  // views::ContextMenuController:
  void ShowContextMenuForViewImpl(View* source,
                                  const gfx::Point& point,
                                  ui::MenuSourceType source_type) override;

  // DownloadUIModel::Observer:
  void OnDownloadUpdated() override;
  void OnDownloadOpened() override;
  void OnDownloadDestroyed() override;

  // views::AnimationDelegateViews:
  void AnimationProgressed(const gfx::Animation* animation) override;
  void AnimationEnded(const gfx::Animation* animation) override;

  // Returns the DownloadUIModel object belonging to this item.
  DownloadUIModel* model() { return model_.get(); }
  const DownloadUIModel* model() const { return model_.get(); }

  // Submits download to download feedback service if the user has approved and
  // the download is suitable for submission, then applies |command|.
  // If user hasn't seen SBER opt-in text before, show SBER opt-in dialog first.
  void MaybeSubmitDownloadToFeedbackService(DownloadCommands::Command command);

  std::u16string GetStatusTextForTesting() const;
  void OpenItemForTesting();

 protected:
  // views::View:
  gfx::Size CalculatePreferredSize() const override;
  void OnPaintBackground(gfx::Canvas* canvas) override;
  void OnPaint(gfx::Canvas* canvas) override;
  void OnThemeChanged() override;

  // ui::LayerDelegate:
  void OnDeviceScaleFactorChanged(float old_device_scale_factor,
                                  float new_device_scale_factor) override;

 private:
  class ContextMenuButton;

  // Sets the current mode to |mode| and updates UI appropriately.
  void SetMode(download::DownloadItemMode mode);
  download::DownloadItemMode GetMode() const;

  // Updates the file path, and if necessary, begins loading the file icon in
  // various sizes. This may eventually result in a callback to
  // OnFileIconLoaded().
  void UpdateFilePathAndIcons();

  // Begins loading the file icon in various sizes.
  void StartLoadIcons();

  // Updates the visibility, text, size, etc. of all labels.
  void UpdateLabels();

  // Updates the visible and enabled state of all buttons.
  void UpdateButtons();

  // Updates the accessible alert and animation-related state for normal mode.
  void UpdateAccessibleAlertAndAnimationsForNormalMode();

  // Update accessible status text, and announce it if desired.
  void UpdateAccessibleAlert(const std::u16string& alert);

  // Updates the animation used during deep scanning. The animation is started
  // or stopped depending on the current mode.
  void UpdateAnimationForDeepScanningMode();

  // Get the accessible alert text for a download that is currently in progress.
  std::u16string GetInProgressAccessibleAlertText() const;

  // Callback for |accessible_update_timer_|, or can be used to ask a screen
  // reader to speak the current alert immediately.
  void AnnounceAccessibleAlert();

  // Sets |file_icon_| to |icon|. Called when the icon manager has loaded the
  // normal-size icon for the current file path.
  void OnFileIconLoaded(IconLoader::IconSize icon_size, gfx::Image icon);

  // Paint the common download animation progress foreground and background. If
  // |percent_done| < 0, the total size is indeterminate.
  // |indeterminate_progress_time| is only used in that case.
  void PaintDownloadProgress(gfx::Canvas* canvas,
                             const gfx::RectF& bounds,
                             const base::TimeDelta& indeterminate_progress_time,
                             int percent_done) const;

  // When not in normal mode, returns the current help/warning/error icon.
  ui::ImageModel GetIcon() const;

  // When not in nromal mode, returns the bounds of the current icon.
  gfx::RectF GetIconBounds() const;

  // Returns the text and style to use for the status label.
  std::pair<std::u16string, int> GetStatusTextAndStyle() const;

  // Returns the size of any button visible next to the label (all visible
  // buttons are given the same size).
  gfx::Size GetButtonSize() const;

  // Returns the file name to report to the user. It might be elided to fit into
  // the text width. |label| dictates the default text style.
  std::u16string ElidedFilename(const views::Label& label) const;
  std::u16string ElidedFilename(const views::StyledLabel& label) const;

  // Returns the Y coordinate that centers |element_height| within the current
  // height().
  int CenterY(int element_height) const;

  // Returns either:
  //   * 200, if |label| can fit in one line given at most 200 DIP width.
  //   * The minimum width needed to display |label| on two lines.
  int GetLabelWidth(const views::StyledLabel& label) const;

  // Sets the state and triggers a repaint.
  void SetDropdownPressed(bool pressed);
  bool GetDropdownPressed() const;

  // Sets |dropdown_button_| to have the correct image for the current state.
  void UpdateDropdownButtonImage();

  // Called when various buttons are pressed.
  void OpenButtonPressed();
  void SaveOrDiscardButtonPressed(DownloadCommands::Command command);
  void DropdownButtonPressed(const ui::Event& event);
  void ReviewButtonPressed();

  // Shows an appropriate prompt dialog when the user hits the "open" button
  // when not in normal mode.
  void ShowOpenDialog(content::WebContents* web_contents);

  // Shows the context menu at the specified location. |point| is in the view's
  // coordinate system.
  void ShowContextMenuImpl(const gfx::Rect& rect,
                           ui::MenuSourceType source_type);

  // Opens a file while async scanning is still pending.
  void OpenDownloadDuringAsyncScanning();

  // Submits the downloaded file to the safebrowsing download feedback service.
  // Applies |command| if submission succeeds. Returns whether submission was
  // successful.
  bool SubmitDownloadToFeedbackService(DownloadCommands::Command command) const;

  // Forwards |command| to |commands_|; useful for callbacks.
  void ExecuteCommand(DownloadCommands::Command command);

  // The model controlling this object's state.
  const DownloadUIModel::DownloadUIModelPtr model_;

  // A utility object to help execute commands on the model.
  DownloadCommands commands_{model()->GetWeakPtr()};

  // The download shelf that owns us.
  const raw_ptr<DownloadShelfView> shelf_;

  // Mode of the download item view.
  download::DownloadItemMode mode_;

  // The "open download" button. This button is visually transparent and fills
  // the entire bounds of the DownloadItemView, to make the DownloadItemView
  // itself seem to be clickable while not requiring DownloadItemView itself to
  // be a button. This is necessary because buttons are not allowed to have
  // children in macOS Accessibility, and to avoid reimplementing much of the
  // button logic in DownloadItemView.
  raw_ptr<views::Button> open_button_;

  // Whether we are dragging the download button.
  bool dragging_ = false;

  // Position that a possible drag started at.
  absl::optional<gfx::Point> drag_start_point_;

  gfx::ImageSkia file_icon_;

  // Tracks in-progress file icon loading tasks.
  base::CancelableTaskTracker cancelable_task_tracker_;

  // |file_icon_| is based on the path of the downloaded item.  Store the path
  // used, so that we can detect a change in the path and reload the icon.
  base::FilePath file_path_;

  raw_ptr<views::Label> file_name_label_;
  raw_ptr<views::Label> status_label_;
  raw_ptr<views::StyledLabel> warning_label_;
  raw_ptr<views::StyledLabel> deep_scanning_label_;

  views::MdTextButton* open_now_button_;
  views::MdTextButton* save_button_;
  views::MdTextButton* discard_button_;
  views::MdTextButton* scan_button_;
  views::MdTextButton* review_button_;
  raw_ptr<views::ImageButton> dropdown_button_;

  // Whether the dropdown is currently pressed.
  bool dropdown_pressed_ = false;

  DownloadShelfContextMenuView context_menu_{this};

  base::RepeatingTimer indeterminate_progress_timer_;

  // The start of the most recent active period of downloading a file of
  // indeterminate size.
  base::TimeTicks indeterminate_progress_start_time_;

  // The total active time downloading a file of indeterminate size.
  base::TimeDelta indeterminate_progress_time_elapsed_;

  gfx::SlideAnimation complete_animation_{this};

  gfx::ThrobAnimation scanning_animation_{this};

  // The tooltip.  Only displayed when not showing a warning dialog.
  std::u16string tooltip_text_;

  std::u16string accessible_name_;

  // A hidden view for accessible status alerts that are spoken by screen
  // readers when a download changes state.
  const raw_ptr<views::View> accessible_alert_;

  // A timer for accessible alerts that helps reduce the number of similar
  // messages spoken in a short period of time.
  base::RepeatingTimer accessible_alert_timer_;

  // Forces reading the current alert text the next time it updates.
  bool announce_accessible_alert_soon_ = false;

  float current_scale_;

  base::ScopedObservation<DownloadUIModel, DownloadUIModel::Observer>
      observation_{this};

  // Whether or not a histogram has been emitted recording that the dropdown
  // button shown.
  bool dropdown_button_shown_recorded_ = false;

  // Whether or not a histogram has been emitted recording that the dropdown
  // button was pressed.
  bool dropdown_button_pressed_recorded_ = false;

  // Method factory used to delay reenabling of the item when opening the
  // downloaded file.
  base::WeakPtrFactory<DownloadItemView> weak_ptr_factory_{this};
};

#endif  // CHROME_BROWSER_UI_VIEWS_DOWNLOAD_DOWNLOAD_ITEM_VIEW_H_


text:
layout:         default
title:          My Photo Gallery
permalink:      /gallery.html
image_folder:   /gallery/photos/
sort_by:        modified_time
date_format:    "%A, %B %-d, %Y"
---

	<link rel="stylesheet" href="public/justified-gallery/css/justifiedGallery.min.css" />
	<link rel="stylesheet" href="public/jquery-colorbox/example5/colorbox.css" />

{{ page.title }}

	    {% assign imgs = site.static_files | sort: page.sort_by %}
	    {% for img in imgs reversed %}
	    {% if img.path contains page.image_folder %}
	    {% assign img_name = img.path | remove: page.image_folder | split: '.' | first %}
	    {% assign img_date = img.modified_time | date: page.date_format %}

	    {% endif %}
	    {% endfor %}


text:
package com.opengamma.master.position.impl;

import java.net.URI;

import javax.ws.rs.core.UriBuilder;

/**
 * RESTful URIs for positions.
 */
public class DataPositionMasterUris {

  /**
   * Builds a URI.
   *
   * @param baseUri  the base URI, not null
   * @return the URI, not null
   */
  public static URI uriSearch(final URI baseUri) {
    final UriBuilder bld = UriBuilder.fromUri(baseUri).path("positionSearches");
    return bld.build();
  }

  /**
   * Builds a URI.
   *
   * @param baseUri  the base URI, not null
   * @return the URI, not null
   */
  public static URI uriAdd(final URI baseUri) {
    final UriBuilder bld = UriBuilder.fromUri(baseUri).path("positions");
    return bld.build();
  }

}


text:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="de.w_hs.keylessentry.activities.ShowDoorActivity">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/name"
            android:paddingBottom="@dimen/activity_vertical_margin" />

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/door_name"
                android:textStyle="bold"
                android:paddingBottom="@dimen/activity_vertical_margin" />
        </ScrollView>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/phoneid"
            android:paddingBottom="@dimen/activity_vertical_margin" />

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/door_ownid"
                android:textStyle="bold"
                android:paddingBottom="@dimen/activity_vertical_margin" />
        </ScrollView>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/doorid"
            android:paddingBottom="@dimen/activity_vertical_margin" />

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/door_remoteid"
                android:textStyle="bold"
                android:paddingBottom="@dimen/activity_vertical_margin" />
        </ScrollView>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/secret"
            android:paddingBottom="@dimen/activity_vertical_margin" />

        <ScrollView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/door_secret"
                android:textStyle="bold" />
        </ScrollView>

    </LinearLayout>
</RelativeLayout>


text:
package pro.foundev.java;

import com.datastax.driver.core.Session;
import com.datastax.spark.connector.cql.CassandraConnector;
import org.apache.spark.SparkConf;
import org.apache.spark.SparkContext;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.DataFrame;
import org.apache.spark.sql.hive.HiveContext;

import java.util.List;

public class SparkSqlQuery extends AbstractCassandraConnectorClass {

    public static void main(String[] args){
        new SparkSqlQuery().run();
    }

    @Override
    protected void run() {
        SparkConf conf = new SparkConf(true)
                .set("spark.cassandra.connection.host", "127.0.0.1");
        CassandraConnector connector = CassandraConnector.apply(conf);
        try (Session session = connector.openSession()) {
            session.execute("create keyspace if not exists activity_stream_api with replication = { 'class':'SimpleStrategy', " +
                    "'replication_factor':1 }");
            session.execute("create table if not exists activity_stream_api.tag_activity " +
                    "( activity_id int, tag text, PRIMARY KEY(activity_id, tag) )");
            session.execute("create table if not exists activity_stream_api.activity " +
                    "( activity_id int, activity text, PRIMARY KEY(activity_id) )");
            session.execute("truncate activity_stream_api.activity");
            session.execute("truncate activity_stream_api.tag_activity");
            session.execute("insert into activity_stream_api.activity " +
                    "( activity_id, activity) values ( 1, 'inserted' )");
            session.execute("insert into activity_stream_api.activity " +
                    "( activity_id, activity) values ( 2, 'updated' )");
            session.execute("insert into activity_stream_api.activity " +
                    "( activity_id, activity) values ( 3, 'deleted' )");
            session.execute("insert into activity_stream_api.tag_activity " +
                    "( activity_id, tag) values ( 1, 'us' )");
            session.execute("insert into activity_stream_api.tag_activity " +
                    "( activity_id, tag) values ( 2, 'us' )");
            session.execute("insert into activity_stream_api.tag_activity " +
                    "( activity_id, tag) values ( 3, 'uk' )");
        }

        SparkContext sc = new SparkContext("spark://127.0.0.1:7077", "test", conf);
        HiveContext hc = new HiveContext(sc);

        DataFrame df = hc.sql("select t.tag, count(*) as cnt from activity_stream_api.activity a " +
                "join activity_stream_api.tag_activity t on t.activity_id = a.activity_id group by t.tag order by cnt");
        Row[] rows = df.collect();

        for (Row row: rows){
            String tag = row.getString(0);
            long count= row.getLong(1);
            System.out.println(tag+","+count);
        }
    }
}


text:
/*global require, module, Packages */
var bkItemStack = Packages.org.bukkit.inventory.ItemStack;
var bkMaterial = Packages.org.bukkit.Material;
var items = function(material, amount) {
  material = material.toUpperCase();
  return new bkItemStack(bkMaterial[material], amount);
};

var materials = bkMaterial.values();

for (var i = 0; i < materials.length; i++) {
  var name = ('' + materials[i].name()).toLowerCase();
  name = name.replace(/(_.)/g, function(a) {
    return a.replace(/_/, '').toUpperCase();
  });

  items[name] = (function(material) {
    return function(amount) {
      if (typeof amount == 'undefined') {
        return material;
      }
      if (typeof amount == 'number') {
        return new bkItemStack(material, amount);
      } else {
        return amount == material;
      }
    };
  })(materials[i]);
}

module.exports = items;


text:
/*
dialog_opera.css
===============

This file contains styles to used by all versions of Opera only.
*/

/* Base it on dialog.css, overriding it with styles defined in this file. */
@import url("dialog.css");

/* Opera has problem with box-shadow and td with border-collapse: collapse */
/* inset shadow is mis-aligned */
.cke_dialog_footer
{
	display: block
}


text:
package com.deepoove.poi.tl.plugin;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Test;

import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.config.ConfigureBuilder;
import com.deepoove.poi.plugin.table.MultipleRowTableRenderPolicy;

public class MultipleRowTableRenderPolicyTest {

    @Test
    public void testMultiRow() throws IOException {
        Map<String, Object> params = new HashMap<>();
        params.put("title", "某某某会议");
        params.put("date", new Date());
        params.put("address", "某某会议室");

        List<Report> reports = new ArrayList<>();
        reports.add(new Report("王五", new Date(), "汇报内容1"));
        reports.add(new Report("张三", new Date(), "汇报内容2"));
        reports.add(new Report("李四", new Date(), "汇报内容3"));
        params.put("reports", reports);

        ConfigureBuilder builder = Configure.builder();
        builder.bind("reports", new MultipleRowTableRenderPolicy());
        XWPFTemplate xt = XWPFTemplate.compile("src/test/resources/template/render-multiple-row.docx", builder.build())
                .render(params);
        xt.writeToFile("out_render-multiple-row.docx");
    }

    static class Report {
        private String author;

        private Date time;

        private String content;

        public Report(String author, Date time, String content) {
            this.author = author;
            this.time = time;
            this.content = content;
        }

        public String getAuthor() {
            return author;
        }

        public void setAuthor(String author) {
            this.author = author;
        }

        public Date getTime() {
            return time;
        }

        public void setTime(Date time) {
            this.time = time;
        }

        public String getContent() {
            return content;
        }

        public void setContent(String content) {
            this.content = content;
        }
    }
}


text:
package io.silverware.microservices.silver;

import io.silverware.microservices.SilverWareException;
import io.silverware.microservices.silver.http.ServletDescriptor;

import java.util.List;

/**
 * Provider of an HTTP Server.
 * Typically needed by {@link MonitoringSilverService} and or {@link HttpInvokerSilverService}.
 *
 * @author Martin Večeřa
 */
public interface HttpServerSilverService extends SilverService {

   /**
    * Context property holding an instance of the HTTP server.
    */
   String HTTP_SERVER = "silverware.http.server";

   /**
    * Property with the HTTP port number on which the server listens.
    */
   String HTTP_SERVER_PORT = "silverware.http.port";

   /**
    * Property with the HTTPS port number on which the server listens.
    */
   String HTTPS_SERVER_PORT = "silverware.https.port";

   /**
    * Property with the hostname/IP address on which the server listens.
    */
   String HTTP_SERVER_ADDRESS = "silverware.http.address";

   /**
    * Context path to which REST requests are routed.
    */
   String HTTP_SERVER_REST_CONTEXT_PATH = "silverware.http.rest.context.path";

   /**
    * Mapping of the base REST Servlet.
    */
   String HTTP_SERVER_REST_SERVLET_MAPPING_PREFIX = "silverware.http.rest.servlet.mapping.prefix";

   /**
    * Place where server keystore file is stored.
    */
   String HTTP_SERVER_KEY_STORE = "silverware.http.server.keystore";

   /**
    * Password to the server keystore file.
    */
   String HTTP_SERVER_KEY_STORE_PASSWORD = "silverware.http.server.keystore.password";

   /**
    * Place where server truststore file is stored.
    */
   String HTTP_SERVER_TRUST_STORE = "silverware.http.server.truststore";

   /**
    * Password to the server truststore file.
    */
   String HTTP_SERVER_TRUST_STORE_PASSWORD = "silverware.http.server.truststore.password";

   /**
    * Enables/Disables SSL.
    */
   String HTTP_SERVER_SSL_ENABLED = "silverware.http.server.ssl.enabled";

   /**
    * Default Keystore.
    */
   String DEFAULT_SSL_KEYSTORE = "silverware-server.keystore";

   /**
    * DefaultTruststore.
    */
   String DEFAULT_SSL_TRUSTSTORE = "silverware-server.truststore";

   /**
    * Password to the default Keystore and Truststore
    */
   String DEFAULT_SSL_STORE_PASSWORD = "silverware";

   /**
    * Deploys a servlet on the HTTP server.
    *
    * @param contextPath
    *       Context path where the servlet should be bound.
    * @param deploymentName
    *       Name of the deployment.
    * @param servletDescriptors
    *       A list of descriptions of the servlet(s).
    * @throws SilverWareException
    *       When it was not possible to deploy the servlet(s).
    */
   void deployServlet(final String contextPath, final String deploymentName,
         final List<ServletDescriptor> servletDescriptors) throws SilverWareException;

   /**
    * Tests if this service is deployed. Service is deployed if its underlying HTTP server has started.
    *
    * @return true if this service is deployed; false otherwise
    */
   boolean isDeployed();
}


text:
'''
Show examples of image patches classified arranged by different classification
probabilities. After running the classification experiment, this file can be
run by sourcing in the same ipython environment:
run -i plot-patches-by-classification-score.py
'''

thresholds = [.6, .3, 0]
ncols = 8
nrows = len(thresholds)
for row in range(nrows):
    thresh = thresholds[row]
    idx = np.where(np.logical_and(predictions>thresh, predictions<(thresh+.1)))[0]
    idx = np.random.permutation(idx)
    npatchesperimage = len(ytest)/len(testfiles)
    offset = 0
    for i in range(ncols):
        found = False
        while not found:
            imageidx = idx[i+offset]/npatchesperimage
            patchidx = idx[i+offset] % npatchesperimage
            if patchidx<300:
                found = True
            else:
                offset += 1

        fname = IMAGE_DIR + testfiles[imageidx]
        img = cv2.imread(fname)
        height, width, channels = img.shape
        patchcount = 0
        finished = False
        x = step
        y = step
        while y<height and not finished:
            x = step;
            while (x<width) and not finished:
                if patchcount==patchidx:
                    left = x - size/2
                    right = x + size/2
                    top = y - size/2
                    bottom = y + size/2
                    patch = img[top:bottom, left:right, :]
                    finished = True
                patchcount += 1
                x+=step
            y += step

        plt.subplot(nrows, ncols, row*ncols + i)
        plt.imshow(patch)
        plt.xticks([])
        plt.yticks([])
        if i==1:
            ylabel('%.1f-%.1f' % (thresh, thresh+.1))

plt.savefig('output-patches-by-threshold.pdf', bbox_inches='tight')


text:
class ExecuteCommandHandler {
  constructor(editorSession, commandName) {
    this.editorSession = editorSession
    this.commandName = commandName
  }
  execute(params, context) {
    this.editorSession.executeCommand(this.commandName, params)
  }
}
export default ExecuteCommandHandler


text:
FROM ubuntu:18.04

# For apt to be noninteractive
ENV DEBIAN_FRONTEND noninteractive
ENV DEBCONF_NONINTERACTIVE_SEEN true

# These arguments are just for reuse and not really meant to be customized.
ARG APT_INSTALL="apt-get install --no-install-recommends -y"

ARG PIP_PKGS="sphinx==2.3.1 mkdocs==1.0.4 numpy==1.18.1"
ARG GEM_PKGS="jekyll:4.0.0 jekyll-redirect-from:0.16.0 rouge:3.15.0"

# Install extra needed repos and refresh.
# - CRAN repo
RUN apt-get clean && apt-get update && $APT_INSTALL gnupg ca-certificates && \
  echo 'deb https://cloud.r-project.org/bin/linux/ubuntu bionic-cran35/' >> /etc/apt/sources.list && \
  gpg --keyserver keyserver.ubuntu.com --recv-key E298A3A825C0D65DFD57CBB651716619E084DAB9 && \
  gpg -a --export E084DAB9 | apt-key add - && \
  apt-get clean && \
  rm -rf /var/lib/apt/lists/* && \
  apt-get clean && \
  apt-get update && \
  # Install openjdk 8.
  $APT_INSTALL openjdk-8-jdk && \
  update-alternatives --set java /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java && \
  # Install build / source control tools
  $APT_INSTALL curl wget git maven ivy subversion make gcc lsof libffi-dev \
    pandoc pandoc-citeproc libssl-dev libcurl4-openssl-dev libxml2-dev

ENV PATH "$PATH:/root/.pyenv/bin:/root/.pyenv/shims"
RUN curl -L https://github.com/pyenv/pyenv-installer/raw/dd3f7d0914c5b4a416ca71ffabdf2954f2021596/bin/pyenv-installer | bash
RUN $APT_INSTALL libbz2-dev libreadline-dev libsqlite3-dev
RUN pyenv install 3.7.6
RUN pyenv global 3.7.6
RUN python --version
RUN pip install --upgrade pip
RUN pip --version
RUN pip install $PIP_PKGS

ENV PATH "$PATH:/root/.rbenv/bin:/root/.rbenv/shims"
RUN curl -fsSL https://github.com/rbenv/rbenv-installer/raw/108c12307621a0aa06f19799641848dde1987deb/bin/rbenv-installer | bash
RUN rbenv install 2.7.0
RUN rbenv global 2.7.0
RUN ruby --version
RUN $APT_INSTALL g++
RUN gem --version
RUN gem install --no-document $GEM_PKGS

RUN \
  curl -sL https://deb.nodesource.com/setup_11.x | bash && \
  $APT_INSTALL nodejs

# Install R packages and dependencies used when building.
# R depends on pandoc*, libssl (which are installed above).
RUN \
  $APT_INSTALL r-base r-base-dev && \
  $APT_INSTALL texlive-latex-base texlive texlive-fonts-extra texinfo qpdf && \
  Rscript -e "install.packages(c('curl', 'xml2', 'httr', 'devtools', 'testthat', 'knitr', 'rmarkdown', 'roxygen2', 'e1071', 'survival'), repos='https://cloud.r-project.org/')" && \
  Rscript -e "devtools::install_github('jimhester/lintr')"

WORKDIR /opt/spark-rm/output

ARG UID
RUN useradd -m -s /bin/bash -p spark-rm -u $UID spark-rm
USER spark-rm:spark-rm

ENTRYPOINT [ "/opt/spark-rm/do-release.sh" ]


text:
"""
EasyBuild support for building and installing numpy, implemented as an easyblock

@author: Stijn De Weirdt (Ghent University)
@author: Dries Verdegem (Ghent University)
@author: Kenneth Hoste (Ghent University)
@author: Pieter De Baets (Ghent University)
@author: Jens Timmerman (Ghent University)
"""
import os
import re
import tempfile

import easybuild.tools.environment as env
import easybuild.tools.toolchain as toolchain
from easybuild.easyblocks.generic.fortranpythonpackage import FortranPythonPackage
from easybuild.tools.build_log import EasyBuildError
from easybuild.tools.filetools import rmtree2
from easybuild.tools.modules import get_software_root
from easybuild.tools.run import run_cmd

class EB_numpy(FortranPythonPackage):
    """Support for installing the numpy Python package as part of a Python installation."""

    def __init__(self, *args, **kwargs):
        """Initialize numpy-specific class variables."""
        super(EB_numpy, self).__init__(*args, **kwargs)

        self.sitecfg = None
        self.sitecfgfn = 'site.cfg'
        self.installopts = ''
        self.testinstall = True
        self.testcmd = "cd .. && python -c 'import numpy; numpy.test(verbose=2)'"

    def configure_step(self):
        """Configure numpy build by composing site.cfg contents."""

        # see e.g. https://github.com/numpy/numpy/pull/2809/files
        self.sitecfg = '\n'.join([
                "[DEFAULT]",
                "library_dirs = %(libs)s",
                "include_dirs= %(includes)s",
                "search_static_first=True",
            ])

        if get_software_root("imkl"):

            if self.toolchain.comp_family() == toolchain.GCC:
                # see https://software.intel.com/en-us/articles/numpyscipy-with-intel-mkl,
                # section Building with GNU Compiler chain
                extrasiteconfig = '\n'.join([
                    "[mkl]",
                    "lapack_libs = ",
                    "mkl_libs = mkl_rt",
                ])
            else:
                extrasiteconfig = '\n'.join([
                    "[mkl]",
                    "lapack_libs = %(lapack)s",
                    "mkl_libs = %(blas)s",
                ])

        else:
            # [atlas] the only real alternative, even for non-ATLAS BLAS libs (e.g., OpenBLAS, ACML, ...)
            # using only the [blas] and [lapack] sections results in sub-optimal builds that don't provide _dotblas.so;
            # it does require a CBLAS interface to be available for the BLAS library being used
            # e.g. for ACML, the CBLAS module providing a C interface needs to be used
            extrasiteconfig = '\n'.join([
                "[atlas]",
                "atlas_libs = %(lapack)s",
                "[lapack]",
                "lapack_libs = %(lapack)s",  # required by scipy, that uses numpy's site.cfg
            ])

        blas = None
        lapack = None
        fft = None

        if get_software_root("imkl"):
            # with IMKL, no spaces and use '-Wl:'
            # redefine 'Wl,' to 'Wl:' so that the patch file can do its job
            def get_libs_for_mkl(varname):
                """Get list of libraries as required for MKL patch file."""
                libs = self.toolchain.variables['LIB%s' % varname].copy()
                libs.try_remove(['pthread'])
                tweaks = {
                    'prefix': '',
                    'prefix_begin_end': '-Wl:',
                    'separator': ',',
                    'separator_begin_end': ',',
                }
                libs.try_function_on_element('change', kwargs=tweaks)
                libs.SEPARATOR = ','
                return str(libs)  # str causes list concatenation and adding prefixes & separators

            blas = get_libs_for_mkl('BLAS_MT')
            lapack = get_libs_for_mkl('LAPACK_MT')
            fft = get_libs_for_mkl('FFT')

            # make sure the patch file is there
            # we check for a typical characteristic of a patch file that cooperates with the above
            # not fool-proof, but better than enforcing a particular patch filename
            patch_found = False
            patch_wl_regex = re.compile(r"replace\(':',\s*','\)")
            for patch in self.patches:
                # patches are either strings (extension) or dicts (easyblock)
                if isinstance(patch, dict):
                    patch = patch['path']
                if patch_wl_regex.search(open(patch, 'r').read()):
                    patch_found = True
                    break
            if not patch_found:
                raise EasyBuildError("Building numpy on top of Intel MKL requires a patch to "
                                     "handle -Wl linker flags correctly, which doesn't seem to be there.")

        else:
            # unless Intel MKL is used, $ATLAS should be set to take full control,
            # and to make sure a fully optimized version is built, including _dotblas.so
            # which is critical for decent performance of the numpy.dot (matrix dot product) function!
            env.setvar('ATLAS', '1')

            lapack = ', '.join([x for x in self.toolchain.get_variable('LIBLAPACK_MT', typ=list) if x != "pthread"])
            fft = ', '.join(self.toolchain.get_variable('LIBFFT', typ=list))

        libs = ':'.join(self.toolchain.get_variable('LDFLAGS', typ=list))
        includes = ':'.join(self.toolchain.get_variable('CPPFLAGS', typ=list))

        # CBLAS is required for ACML, because it doesn't offer a C interface to BLAS
        if get_software_root('ACML'):
            cblasroot = get_software_root('CBLAS')
            if cblasroot:
                lapack = ', '.join([lapack, "cblas"])
                cblaslib = os.path.join(cblasroot, 'lib')
                # with numpy as extension, CBLAS might not be included in LDFLAGS because it's not part of a toolchain
                if not cblaslib in libs:
                    libs = ':'.join([libs, cblaslib])
            else:
                raise EasyBuildError("CBLAS is required next to ACML to provide a C interface to BLAS, "
                                     "but it's not loaded.")

        if fft:
            extrasiteconfig += "\n[fftw]\nlibraries = %s" % fft

        self.sitecfg = '\n'.join([self.sitecfg, extrasiteconfig])

        self.sitecfg = self.sitecfg % {
            'blas': blas,
            'lapack': lapack,
            'libs': libs,
            'includes': includes,
        }

        super(EB_numpy, self).configure_step()

        # check configuration (for debugging purposes)
        cmd = "python setup.py config"
        run_cmd(cmd, log_all=True, simple=True)

    def test_step(self):
        """Run available numpy unit tests, and more."""
        super(EB_numpy, self).test_step()

        # temporarily install numpy, it doesn't alow to be used straight from the source dir
        tmpdir = tempfile.mkdtemp()
        cmd = "python setup.py install --prefix=%s %s" % (tmpdir, self.installopts)
        run_cmd(cmd, log_all=True, simple=True)

        try:
            pwd = os.getcwd()
            os.chdir(tmpdir)
        except OSError, err:
            raise EasyBuildError("Faild to change to %s: %s", tmpdir, err)

        # evaluate performance of numpy.dot (3 runs, 3 loops each)
        size = 1000
        max_time_msec = 1000  # 1 second should really do it for a 1000x1000 matrix dot product
        cmd = ' '.join([
            'export PYTHONPATH=%s:$PYTHONPATH &&' % os.path.join(tmpdir, self.pylibdir),
            'python -m timeit -n 3 -r 3',
            '-s "import numpy; x = numpy.random.random((%(size)d, %(size)d))"' % {'size': size},
            '"numpy.dot(x, x.T)"',
        ])
        (out, ec) = run_cmd(cmd, simple=False)
        self.log.debug("Test output: %s" % out)

        # fetch result
        time_msec = None
        msec_re = re.compile("\d+ loops, best of \d+: (?P<time>[0-9.]+) msec per loop")
        res = msec_re.search(out)
        if res:
            time_msec = float(res.group('time'))
        else:
            sec_re = re.compile("\d+ loops, best of \d+: (?P<time>[0-9.]+) sec per loop")
            res = sec_re.search(out)
            if res:
                time_msec = 1000 * float(res.group('time'))
            else:
                raise EasyBuildError("Failed to determine time for numpy.dot test run.")

        # make sure we observe decent performance
        if time_msec < max_time_msec:
            self.log.info("Time for %dx%d matrix dot product: %d msec < %d msec => OK",
                          size, size, time_msec, max_time_msec)
        else:
            raise EasyBuildError("Time for %dx%d matrix dot product: %d msec >= %d msec => ERROR",
                                 size, size, time_msec, max_time_msec)
        try:
            os.chdir(pwd)
            rmtree2(tmpdir)
        except OSError, err:
            raise EasyBuildError("Failed to change back to %s: %s", pwd, err)

    def sanity_check_step(self, *args, **kwargs):
        """Custom sanity check for numpy."""

        custom_paths = {
            'files': [os.path.join(self.pylibdir, 'numpy', '__init__.py')],
            'dirs': [],
        }
        custom_commands = [
            ('python', '-c "import numpy"'),
            ('python', '-c "import numpy.core._dotblas"'),  # _dotblas is required for decent performance of numpy.dot()
        ]

        # make sure the installation path is in $PYTHONPATH so the sanity check commands can work
        pythonpath = os.environ.get('PYTHONPATH', '')
        os.environ['PYTHONPATH'] = ':'.join([self.pylibdir, pythonpath])

        return super(EB_numpy, self).sanity_check_step(custom_paths=custom_paths, custom_commands=custom_commands)

    def install_step(self):
        """Install numpy and remove numpy build dir, so scipy doesn't find it by accident."""
        super(EB_numpy, self).install_step()

        builddir = os.path.join(self.builddir, "numpy")
        if os.path.isdir(builddir):
            rmtree2(builddir)
        else:
            self.log.debug("build dir %s already clean" % builddir)


text:
ExRx.net Summer 2017 Internship Project

Created registration and login webpages that would store personal information to Firebase (NoSQL database). Furthermore, I incorporated a method to allow users to add exercises to their personal account using Javascript, HTML, CSS, and jQuery.

Link: www.exrx.net


text:
<?php

namespace CodeIgniter\Commands\Utilities\Routes;

use CodeIgniter\Test\CIUnitTestCase;

/**
 * @internal
 */
final class ControllerFinderTest extends CIUnitTestCase
{
    public function testFind()
    {
        $namespace = 'Tests\Support\Controllers';
        $finder    = new ControllerFinder($namespace);

        $controllers = $finder->find();

        $this->assertCount(3, $controllers);
        $this->assertSame('Tests\Support\Controllers\Hello', $controllers[0]);
    }
}