text:
MDXS Consulting Ltd. Privacy Policy
MDXS Consulting Ltd. ("MDXS") has created this privacy policy ("Privacy Policy") in order to set out how we collect, use, and disclose personal information, including through The MD Exit Strategy ("MDXS community") that allows our registered members ("members") to create profiles and monitor cognitive patterns of end users ("End Users").
The privacy of our users is of great importance to us. By visiting our website located at https://www.mdxs.ca (the "Website") or participating in the MDXS Forum (the "Forum") or related services in any manner (collectively, the "Services"), you acknowledge that you accept the practices and policies outlined in this Privacy Policy and you hereby consent to the collection, use and disclosure of your personal information in accordance with this Privacy Policy.
WHAT DOES THIS PRIVACY POLICY COVER?
This Privacy Policy covers our collection, use and disclosure of information about identifiable individuals ("Personal Information"). This Privacy Policy does not apply to the practices of companies that we do not own or control, including those of our Clients.
COLLECTION AND USE OF PERSONAL INFORMATION AND OTHER DATA
2.1. MDXS Account Information
In order to enter the MDXS community, users must have a valid MDXS membership account ("Account"). When a user registers for the community, MDXS collects the user's first and last name, email address, and phone number, in order to uniquely identify the user, authenticate Account access, and provide access to the Community. MDXS also uses the email address and phone number to communicate with the user regarding Client requests, product information and support matters.
2.2. Website Data
MDXS may also collect certain information from users of the Website through web forms that collect your first name, last name, email address, phone number, and company name, and may also collect Internet addresses, time spent logged into the website, and other usage data ("Website Data"). This information is logged to respond to user queries, provide ongoing email updates, and to constantly improve the quality of the Services.
The Website uses technologies such as cookies, beacons, scripts, and tags. These technologies may be used for analyzing trends, administering the website, tracking users' movements around the website, and gathering demographic information about our user base as a whole. Various browsers may offer their own management tools for removing these types of tracking technologies.
2.3. End User Data
When an End User registers for an Account on the Community, MDXS collects first name, last name, phone number, physician college membership and registration number (the "End User Data"). This information is collected to allow the End User to create and maintain a profile on the Community and use the Services.
2.4 Anonymized Data
Client acknowledges and agrees that MDXS compiles and analyzes End User Data to create useful, aggregated information about client service delivery and performance and accordingly MDXS requires the right to generate data about the use and operation of the Community and delivery of the Services, from reports generated pursuant to this Agreement and raw End User Data ("Analytics Data"). Client hereby grants MDXS a perpetual, worldwide, non-exclusive, royalty-free license to create Analytics Data from End User Data and combine it in whole or in part with data derived through the use of the Services and with other data at MDXS's discretion. For the avoidance of doubt, Analytics Data will not include any raw End User Data, including any personal information or personal health information, and will not be distributed in a manner which identifies Client. MDXS shall have exclusive ownership of any Analytics Data and the exclusive right to use the same for any purpose without restriction.
STORAGE LOCATION AND TRANSFER OF PERSONAL INFORMATION
MDXS stores its Website Data, including Personal Information, on servers located in the United States. By submitting information, you agree to this transfer, storing or processing of your Personal Information in the U.S.. You acknowledge and agree that your Personal Information may be accessible to law enforcement and governmental agencies in those countries under lawful access regimes or court order.
DISCLOSURE OF PERSONAL INFORMATION WITH THIRD PARTIES
4.1. Service Providers and Business Partners
We may from time to time employ other companies and people to perform tasks on our behalf and need to share Client Personal Information with them to provide the Community and related Services. Unless we tell you differently, such third parties do not have any right to use the Personal Information we share with them beyond what is necessary to assist us. This includes third party companies and individuals employed by us to facilitate our Services, including the provision of software licensing, maintenance services, database management, Web analytics and general improvement of the Community and related Services.We use Infusionsoft/KEAP software to collect information and communicate with our members. Please review Infusionsoft's privacy policy.
4.2. Business Transfers
If we (or substantially all of our assets) are acquired, or if we go out of business, enter bankruptcy, or go through some other change of control, Personal Information may be made available or otherwise transferred to the new controlling entity, where permitted under applicable law.
4.3. With Your Consent
If we need to use or disclose any Personal Information in a way not identified in this Privacy Policy, we will notify you and/or obtain your express consent as required under applicable privacy laws. Moreover, MDXS will only share Personal Information with your school, team, coaching staff or physician with your express consent.
We will keep your Personal Information for as long as it remains necessary for the identified purpose or as required by law, which may extend beyond the termination of our relationship with you. We may retain certain data as necessary to prevent fraud or future abuse, or for legitimate business purposes, such as analysis of aggregated, non-personally-identifiable data, account recovery, or if required by law. All retained Personal Information will remain subject to the terms of this Privacy Policy.
ACCESS, CORRECTION AND ACCURACY
You have the right to access the Personal Information we hold about you in order to verify the Personal Information we have collected in respect to you and to have a general account of our uses of that information. Upon receipt of your written request, we will provide you with a copy of your Personal Information, although in certain limited circumstances, and as permitted under law, we may not be able to make all relevant information available to you, such as where that information also pertains to another user. In such circumstances we will provide reasons for the denial to you upon request. We will endeavor to deal with all requests for access and modifications in a timely manner.
We will make every reasonable effort to keep your Personal Information accurate and up to date, and we will provide you with mechanisms to update, correct, delete or add to your Personal Information as appropriate. As appropriate, this amended Personal Information will be transmitted to those parties to which we are permitted to disclose your information. Having accurate Personal Information about you enables us to give you the best possible service.
We may amend this Privacy Policy from time to time. Use of Personal Information we collect is subject to the Privacy Policy in effect at the time such information is collected, used or disclosed. If we make material changes or changes in the way we use Personal Information, we will notify you by posting an announcement on our Website or sending you an email prior to the change becoming effective. You are bound by any changes to the Privacy Policy when you use the Website after such changes have been first posted.
Questions regarding this Privacy Policy or MDXS's privacy practices should be directed to MDXS


text:
/*
htop - Process.c
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/

#include "Process.h"

#include "ProcessList.h"
#include "CRT.h"
#include "String.h"
#include "RichString.h"

#include <stdio.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <stdbool.h>
#include <pwd.h>
#include <sched.h>
#include <time.h>
#include <assert.h>
#include <sys/syscall.h>

#ifdef HAVE_LIBHWLOC
#include <hwloc/linux.h>
#endif

// This works only with glibc 2.1+. On earlier versions
// the behavior is similar to have a hardcoded page size.
#ifndef PAGE_SIZE
#define PAGE_SIZE ( sysconf(_SC_PAGESIZE) )
#endif
#define PAGE_SIZE_KB ( PAGE_SIZE / ONE_K )

/*{
#include "Object.h"
#include "Affinity.h"
#include "IOPriority.h"
#include <sys/types.h>

#ifndef Process_isKernelThread
#define Process_isKernelThread(_process) (_process->pgrp == 0)
#endif

#ifndef Process_isUserlandThread
#define Process_isUserlandThread(_process) (_process->pid != _process->tgid)
#endif

#ifndef Process_isThread
#define Process_isThread(_process) (Process_isUserlandThread(_process) || Process_isKernelThread(_process))
#endif

typedef enum ProcessField_ {
   PID = 1, COMM, STATE, PPID, PGRP, SESSION, TTY_NR, TPGID, FLAGS, MINFLT, CMINFLT, MAJFLT, CMAJFLT, UTIME,
   STIME, CUTIME, CSTIME, PRIORITY, NICE, ITREALVALUE, STARTTIME, VSIZE, RSS, RLIM, STARTCODE, ENDCODE,
   STARTSTACK, KSTKESP, KSTKEIP, SIGNAL, BLOCKED, SSIGIGNORE, SIGCATCH, WCHAN, NSWAP, CNSWAP, EXIT_SIGNAL,
   PROCESSOR, M_SIZE, M_RESIDENT, M_SHARE, M_TRS, M_DRS, M_LRS, M_DT, ST_UID, PERCENT_CPU, PERCENT_MEM,
   USER, TIME, NLWP, TGID,
   #ifdef HAVE_OPENVZ
   CTID, VPID,
   #endif
   #ifdef HAVE_VSERVER
   VXID,
   #endif
   #ifdef HAVE_TASKSTATS
   RCHAR, WCHAR, SYSCR, SYSCW, RBYTES, WBYTES, CNCLWB, IO_READ_RATE, IO_WRITE_RATE, IO_RATE,
   #endif
   #ifdef HAVE_CGROUP
   CGROUP,
   #endif
   IO_PRIORITY,
   LAST_PROCESSFIELD
} ProcessField;

struct ProcessList_;

typedef struct Process_ {
   Object super;

   struct ProcessList_ *pl;
   bool updated;

   pid_t pid;
   char* comm;
   int indent;
   char state;
   bool tag;
   bool showChildren;
   bool show;
   pid_t ppid;
   unsigned int pgrp;
   unsigned int session;
   unsigned int tty_nr;
   pid_t tgid;
   int tpgid;
   unsigned long int flags;
   #ifdef DEBUG
   unsigned long int minflt;
   unsigned long int cminflt;
   unsigned long int majflt;
   unsigned long int cmajflt;
   #endif
   unsigned long long int utime;
   unsigned long long int stime;
   unsigned long long int cutime;
   unsigned long long int cstime;
   long int priority;
   long int nice;
   long int nlwp;
   IOPriority ioPriority;
   char starttime_show[8];
   time_t starttime_ctime;
   #ifdef DEBUG
   long int itrealvalue;
   unsigned long int vsize;
   long int rss;
   unsigned long int rlim;
   unsigned long int startcode;
   unsigned long int endcode;
   unsigned long int startstack;
   unsigned long int kstkesp;
   unsigned long int kstkeip;
   unsigned long int signal;
   unsigned long int blocked;
   unsigned long int sigignore;
   unsigned long int sigcatch;
   unsigned long int wchan;
   unsigned long int nswap;
   unsigned long int cnswap;
   #endif
   int exit_signal;
   int processor;
   int m_size;
   int m_resident;
   int m_share;
   int m_trs;
   int m_drs;
   int m_lrs;
   int m_dt;
   uid_t st_uid;
   float percent_cpu;
   float percent_mem;
   char* user;
   #ifdef HAVE_OPENVZ
   unsigned int ctid;
   unsigned int vpid;
   #endif
   #ifdef HAVE_VSERVER
   unsigned int vxid;
   #endif
   #ifdef HAVE_TASKSTATS
   unsigned long long io_rchar;
   unsigned long long io_wchar;
   unsigned long long io_syscr;
   unsigned long long io_syscw;
   unsigned long long io_read_bytes;
   unsigned long long io_write_bytes;
   unsigned long long io_cancelled_write_bytes;
   double io_rate_read_bps;
   unsigned long long io_rate_read_time;
   double io_rate_write_bps;
   unsigned long long io_rate_write_time;
   #endif
   #ifdef HAVE_CGROUP
   char* cgroup;
   #endif
} Process;

}*/

#ifdef DEBUG
char* PROCESS_CLASS = "Process";
#else
#define PROCESS_CLASS NULL
#endif

const char *Process_fieldNames[] = {
   "", "PID", "Command", "STATE", "PPID", "PGRP", "SESSION",
   "TTY_NR", "TPGID", "FLAGS", "MINFLT", "CMINFLT", "MAJFLT", "CMAJFLT",
   "UTIME", "STIME", "CUTIME", "CSTIME", "PRIORITY", "NICE", "ITREALVALUE",
   "STARTTIME", "VSIZE", "RSS", "RLIM", "STARTCODE", "ENDCODE", "STARTSTACK",
   "KSTKESP", "KSTKEIP", "SIGNAL", "BLOCKED", "SIGIGNORE", "SIGCATCH", "WCHAN",
   "NSWAP", "CNSWAP", "EXIT_SIGNAL", "PROCESSOR", "M_SIZE", "M_RESIDENT", "M_SHARE",
   "M_TRS", "M_DRS", "M_LRS", "M_DT", "ST_UID", "PERCENT_CPU", "PERCENT_MEM",
   "USER", "TIME", "NLWP", "TGID",
#ifdef HAVE_OPENVZ
   "CTID", "VPID",
#endif
#ifdef HAVE_VSERVER
   "VXID",
#endif
#ifdef HAVE_TASKSTATS
   "RCHAR", "WCHAR", "SYSCR", "SYSCW", "RBYTES", "WBYTES", "CNCLWB",
   "IO_READ_RATE", "IO_WRITE_RATE", "IO_RATE",
#endif
#ifdef HAVE_CGROUP
   "CGROUP",
#endif
   "IO_PRIORITY",
"*** report bug! ***"
};

const char *Process_fieldTitles[] = {
   "", "    PID ", "Command ", "S ", "   PPID ", "   PGRP ", "   SESN ",
   "  TTY ", "  TPGID ", "- ", "- ", "- ", "- ", "- ",
   " UTIME+  ", " STIME+  ", " CUTIME+ ", " CSTIME+ ", "PRI ", " NI ", "- ",
   "START ", "- ", "- ", "- ", "- ", "- ", "- ",
   "- ", "- ", "- ", "- ", "- ", "- ", "- ",
   "- ", "- ", "- ", "CPU ", " VIRT ", "  RES ", "  SHR ",
   " CODE ", " DATA ", " LIB ", " DIRTY ", " UID ", "CPU% ", "MEM% ",
   "USER      ", "  TIME+  ", "NLWP ", "   TGID ",
#ifdef HAVE_OPENVZ
   " CTID ", " VPID ",
#endif
#ifdef HAVE_VSERVER
   " VXID ",
#endif
#ifdef HAVE_TASKSTATS
   "     RD_CHAR ", "     WR_CHAR ", "   RD_SYSC ", "   WR_SYSC ", "  IO_RBYTES ", "  IO_WBYTES ", " IO_CANCEL ",
   " IORR ", " IOWR ", "   IO ",
#endif
#ifdef HAVE_CGROUP
   "    CGROUP ",
#endif
   "IO ",
"*** report bug! ***"
};

static int Process_getuid = -1;

static char* Process_pidFormat = "%7u ";
static char* Process_tpgidFormat = "%7u ";

void Process_getMaxPid() {
   FILE* file = fopen(PROCDIR "/sys/kernel/pid_max", "r");
   if (!file) return;
   int maxPid = 4194303;
   fscanf(file, "%32d", &maxPid);
   fclose(file);
   if (maxPid > 99999) {
      Process_fieldTitles[PID] =     "    PID ";
      Process_fieldTitles[PPID] =    "   PPID ";
      Process_fieldTitles[TPGID] =   "  TPGID ";
      Process_fieldTitles[TGID] =    "   TGID ";
      Process_fieldTitles[PGRP] =    "   PGRP ";
      Process_fieldTitles[SESSION] = "   SESN ";
      Process_pidFormat = "%7u ";
      Process_tpgidFormat = "%7d ";
   } else {
      Process_fieldTitles[PID] =     "  PID ";
      Process_fieldTitles[PPID] =    " PPID ";
      Process_fieldTitles[TPGID] =   "TPGID ";
      Process_fieldTitles[TGID] =    " TGID ";
      Process_fieldTitles[PGRP] =    " PGRP ";
      Process_fieldTitles[SESSION] = " SESN ";
      Process_pidFormat = "%5u ";
      Process_tpgidFormat = "%5d ";
   }
}

#define ONE_K 1024
#define ONE_M (ONE_K * ONE_K)
#define ONE_G (ONE_M * ONE_K)

static void Process_humanNumber(Process* this, RichString* str, unsigned long number) {
   char buffer[11];
   int len;
   if(number >= (10 * ONE_M)) {
      if(number >= (100 * ONE_M)) {
         len = snprintf(buffer, 10, "%4ldG ", number / ONE_M);
         RichString_appendn(str, CRT_colors[LARGE_NUMBER], buffer, len);
      } else {
         len = snprintf(buffer, 10, "%3.1fG ", (float)number / ONE_M);
         RichString_appendn(str, CRT_colors[LARGE_NUMBER], buffer, len);
      }
   } else if (number >= 100000) {
      len = snprintf(buffer, 10, "%4ldM ", number / ONE_K);
      int attr = this->pl->highlightMegabytes
               ? CRT_colors[PROCESS_MEGABYTES]
               : CRT_colors[PROCESS];
      RichString_appendn(str, attr, buffer, len);
   } else if (this->pl->highlightMegabytes && number >= 1000) {
      len = snprintf(buffer, 10, "%2ld", number/1000);
      RichString_appendn(str, CRT_colors[PROCESS_MEGABYTES], buffer, len);
      number %= 1000;
      len = snprintf(buffer, 10, "%03ld ", number);
      RichString_appendn(str, CRT_colors[PROCESS], buffer, len);
   } else {
      len = snprintf(buffer, 10, "%5ld ", number);
      RichString_appendn(str, CRT_colors[PROCESS], buffer, len);
   }
}

static void Process_colorNumber(RichString* str, unsigned long long number) {
   char buffer[14];
   if (number > 10000000000) {
      snprintf(buffer, 13, "%11lld ", number / 1000);
      RichString_appendn(str, CRT_colors[LARGE_NUMBER], buffer, 5);
      RichString_appendn(str, CRT_colors[PROCESS_MEGABYTES], buffer+5, 3);
      RichString_appendn(str, CRT_colors[PROCESS], buffer+8, 4);
   } else {
      snprintf(buffer, 13, "%11lld ", number);
      RichString_appendn(str, CRT_colors[LARGE_NUMBER], buffer, 2);
      RichString_appendn(str, CRT_colors[PROCESS_MEGABYTES], buffer+2, 3);
      RichString_appendn(str, CRT_colors[PROCESS], buffer+5, 3);
      RichString_appendn(str, CRT_colors[PROCESS_SHADOW], buffer+8, 4);
   }
}

static double jiffy = 0.0;

static void Process_printTime(RichString* str, unsigned long long t) {
   if(jiffy == 0.0) jiffy = sysconf(_SC_CLK_TCK);
   double jiffytime = 1.0 / jiffy;

   double realTime = t * jiffytime;
   unsigned long long iRealTime = (unsigned long long) realTime;

   unsigned long long hours = iRealTime / 3600;
   int minutes = (iRealTime / 60) % 60;
   int seconds = iRealTime % 60;
   int hundredths = (realTime - iRealTime) * 100;
   char buffer[11];
   if (hours >= 100) {
      snprintf(buffer, 10, "%7lluh ", hours);
      RichString_append(str, CRT_colors[LARGE_NUMBER], buffer);
   } else {
      if (hours) {
         snprintf(buffer, 10, "%2lluh", hours);
         RichString_append(str, CRT_colors[LARGE_NUMBER], buffer);
         snprintf(buffer, 10, "%02d:%02d ", minutes, seconds);
      } else {
         snprintf(buffer, 10, "%2d:%02d.%02d ", minutes, seconds, hundredths);
      }
      RichString_append(str, CRT_colors[DEFAULT_COLOR], buffer);
   }
}

static inline void Process_writeCommand(Process* this, int attr, int baseattr, RichString* str) {
   int start = RichString_size(str);
   RichString_append(str, attr, this->comm);
   if (this->pl->highlightBaseName) {
      int finish = RichString_size(str) - 1;
      int space = RichString_findChar(str, ' ', start);
      if (space != -1)
         finish = space - 1;
      for (;;) {
         int slash = RichString_findChar(str, '/', start);
         if (slash == -1 || slash > finish)
            break;
         start = slash + 1;
      }
      RichString_setAttrn(str, baseattr, start, finish);
   }
}

static inline void Process_outputRate(Process* this, RichString* str, int attr, char* buffer, int n, double rate) {
   rate = rate / 1024;
   if (rate < 0.01)
      snprintf(buffer, n, "    0 ");
   else if (rate <= 10)
      snprintf(buffer, n, "%5.2f ", rate);
   else if (rate <= 100)
      snprintf(buffer, n, "%5.1f ", rate);
   else {
      Process_humanNumber(this, str, rate);
      return;
   }
   RichString_append(str, attr, buffer);
}

static void Process_writeField(Process* this, RichString* str, ProcessField field) {
   char buffer[128]; buffer[127] = '\0';
   int attr = CRT_colors[DEFAULT_COLOR];
   int baseattr = CRT_colors[PROCESS_BASENAME];
   int n = sizeof(buffer) - 1;

   switch (field) {
   case PID: snprintf(buffer, n, Process_pidFormat, this->pid); break;
   case PPID: snprintf(buffer, n, Process_pidFormat, this->ppid); break;
   case PGRP: snprintf(buffer, n, Process_pidFormat, this->pgrp); break;
   case SESSION: snprintf(buffer, n, Process_pidFormat, this->session); break;
   case TTY_NR: snprintf(buffer, n, "%5u ", this->tty_nr); break;
   case TGID: snprintf(buffer, n, Process_pidFormat, this->tgid); break;
   case TPGID: snprintf(buffer, n, Process_tpgidFormat, this->tpgid); break;
   case PROCESSOR: snprintf(buffer, n, "%3d ", ProcessList_cpuId(this->pl, this->processor)); break;
   case NLWP: snprintf(buffer, n, "%4ld ", this->nlwp); break;
   case COMM: {
      if (this->pl->highlightThreads && Process_isThread(this)) {
         attr = CRT_colors[PROCESS_THREAD];
         baseattr = CRT_colors[PROCESS_THREAD_BASENAME];
      }
      if (!this->pl->treeView || this->indent == 0) {
         Process_writeCommand(this, attr, baseattr, str);
         return;
      } else {
         char* buf = buffer;
         int maxIndent = 0;
         const char **treeStr = this->pl->treeStr;
         bool lastItem = (this->indent < 0);
         int indent = (this->indent < 0 ? -this->indent : this->indent);
         if (treeStr == NULL)
             treeStr = ProcessList_treeStrAscii;

         for (int i = 0; i < 32; i++)
            if (indent & (1 << i))
               maxIndent = i+1;
          for (int i = 0; i < maxIndent - 1; i++) {
            int written;
            if (indent & (1 << i))
               written = snprintf(buf, n, "%s  ", treeStr[TREE_STR_VERT]);
            else
               written = snprintf(buf, n, "   ");
            buf += written;
            n -= written;
         }
         const char* draw = treeStr[lastItem ? (this->pl->direction == 1 ? TREE_STR_BEND : TREE_STR_TEND) : TREE_STR_RTEE];
         snprintf(buf, n, "%s%s ", draw, this->showChildren ? treeStr[TREE_STR_SHUT] : treeStr[TREE_STR_OPEN] );
         RichString_append(str, CRT_colors[PROCESS_TREE], buffer);
         Process_writeCommand(this, attr, baseattr, str);
         return;
      }
   }
   case STATE: {
      snprintf(buffer, n, "%c ", this->state);
      attr = this->state == 'R'
           ? CRT_colors[PROCESS_R_STATE]
           : attr;
      break;
   }
   case PRIORITY: {
      if(this->priority == -100)
         snprintf(buffer, n, " RT ");
      else
         snprintf(buffer, n, "%3ld ", this->priority);
      break;
   }
   case NICE: {
      snprintf(buffer, n, "%3ld ", this->nice);
      attr = this->nice < 0 ? CRT_colors[PROCESS_HIGH_PRIORITY]
           : this->nice > 0 ? CRT_colors[PROCESS_LOW_PRIORITY]
           : attr;
      break;
   }
   case M_DRS: Process_humanNumber(this, str, this->m_drs * PAGE_SIZE_KB); return;
   case M_DT: Process_humanNumber(this, str, this->m_dt * PAGE_SIZE_KB); return;
   case M_LRS: Process_humanNumber(this, str, this->m_lrs * PAGE_SIZE_KB); return;
   case M_TRS: Process_humanNumber(this, str, this->m_trs * PAGE_SIZE_KB); return;
   case M_SIZE: Process_humanNumber(this, str, this->m_size * PAGE_SIZE_KB); return;
   case M_RESIDENT: Process_humanNumber(this, str, this->m_resident * PAGE_SIZE_KB); return;
   case M_SHARE: Process_humanNumber(this, str, this->m_share * PAGE_SIZE_KB); return;
   case ST_UID: snprintf(buffer, n, "%4d ", this->st_uid); break;
   case USER: {
      if (Process_getuid != (int) this->st_uid)
         attr = CRT_colors[PROCESS_SHADOW];
      if (this->user) {
         snprintf(buffer, n, "%-9s ", this->user);
      } else {
         snprintf(buffer, n, "%-9d ", this->st_uid);
      }
      if (buffer[9] != '\0') {
         buffer[9] = ' ';
         buffer[10] = '\0';
      }
      break;
   }
   case UTIME: Process_printTime(str, this->utime); return;
   case STIME: Process_printTime(str, this->stime); return;
   case CUTIME: Process_printTime(str, this->cutime); return;
   case CSTIME: Process_printTime(str, this->cstime); return;
   case TIME: Process_printTime(str, this->utime + this->stime); return;
   case PERCENT_CPU: {
      if (this->percent_cpu > 999.9) {
         snprintf(buffer, n, "%4d ", (unsigned int)this->percent_cpu);
      } else if (this->percent_cpu > 99.9) {
         snprintf(buffer, n, "%3d. ", (unsigned int)this->percent_cpu);
      } else {
         snprintf(buffer, n, "%4.1f ", this->percent_cpu);
      }
      break;
   }
   case PERCENT_MEM: {
      if (this->percent_mem > 99.9) {
         snprintf(buffer, n, "100. ");
      } else {
         snprintf(buffer, n, "%4.1f ", this->percent_mem);
      }
      break;
   }
   case STARTTIME: snprintf(buffer, n, "%s", this->starttime_show); break;
   #ifdef HAVE_OPENVZ
   case CTID: snprintf(buffer, n, "%5u ", this->ctid); break;
   case VPID: snprintf(buffer, n, "%5u ", this->vpid); break;
   #endif
   #ifdef HAVE_VSERVER
   case VXID: snprintf(buffer, n, "%5u ", this->vxid); break;
   #endif
   #ifdef HAVE_TASKSTATS
   case RCHAR:  snprintf(buffer, n, "%12llu ", this->io_rchar); break;
   case WCHAR:  snprintf(buffer, n, "%12llu ", this->io_wchar); break;
   case SYSCR:  snprintf(buffer, n, "%10llu ", this->io_syscr); break;
   case SYSCW:  snprintf(buffer, n, "%10llu ", this->io_syscw); break;
   case RBYTES: Process_colorNumber(str, this->io_read_bytes); return;
   case WBYTES: Process_colorNumber(str, this->io_write_bytes); return;
   case CNCLWB: snprintf(buffer, n, "%10llu ", this->io_cancelled_write_bytes); break;
   case IO_READ_RATE:  Process_outputRate(this, str, attr, buffer, n, this->io_rate_read_bps); return;
   case IO_WRITE_RATE: Process_outputRate(this, str, attr, buffer, n, this->io_rate_write_bps); return;
   case IO_RATE: Process_outputRate(this, str, attr, buffer, n, this->io_rate_read_bps + this->io_rate_write_bps); return;
   #endif
   #ifdef HAVE_CGROUP
   case CGROUP: snprintf(buffer, n, "%-10s ", this->cgroup); break;
   #endif
   case IO_PRIORITY: {
      int klass = IOPriority_class(this->ioPriority);
      if (klass == IOPRIO_CLASS_NONE) {
         // see note [1] above
         snprintf(buffer, n, "B%1d ", (int) (this->nice + 20) / 5);
      } else if (klass == IOPRIO_CLASS_BE) {
         snprintf(buffer, n, "B%1d ", IOPriority_data(this->ioPriority));
      } else if (klass == IOPRIO_CLASS_RT) {
         attr = CRT_colors[PROCESS_HIGH_PRIORITY];
         snprintf(buffer, n, "R%1d ", IOPriority_data(this->ioPriority));
      } else if (this->ioPriority == IOPriority_Idle) {
         attr = CRT_colors[PROCESS_LOW_PRIORITY];
         snprintf(buffer, n, "id ");
      } else {
         snprintf(buffer, n, "?? ");
      }
      break;
   }
   default:
      snprintf(buffer, n, "- ");
   }
   RichString_append(str, attr, buffer);
}

static void Process_display(Object* cast, RichString* out) {
   Process* this = (Process*) cast;
   ProcessField* fields = this->pl->fields;
   RichString_prune(out);
   for (int i = 0; fields[i]; i++)
      Process_writeField(this, out, fields[i]);
   if (this->pl->shadowOtherUsers && (int)this->st_uid != Process_getuid)
      RichString_setAttr(out, CRT_colors[PROCESS_SHADOW]);
   if (this->tag == true)
      RichString_setAttr(out, CRT_colors[PROCESS_TAG]);
   assert(out->chlen > 0);
}

void Process_delete(Object* cast) {
   Process* this = (Process*) cast;
   assert (this != NULL);
   if (this->comm) free(this->comm);
#ifdef HAVE_CGROUP
   if (this->cgroup) free(this->cgroup);
#endif
   free(this);
}

Process* Process_new(struct ProcessList_ *pl) {
   Process* this = calloc(sizeof(Process), 1);
   Object_setClass(this, PROCESS_CLASS);
   ((Object*)this)->display = Process_display;
   ((Object*)this)->delete = Process_delete;
   this->pid = 0;
   this->pl = pl;
   this->tag = false;
   this->showChildren = true;
   this->show = true;
   this->updated = false;
   this->utime = 0;
   this->stime = 0;
   this->comm = NULL;
   this->indent = 0;
#ifdef HAVE_CGROUP
   this->cgroup = NULL;
#endif
   if (Process_getuid == -1) Process_getuid = getuid();
   return this;
}

void Process_toggleTag(Process* this) {
   this->tag = this->tag == true ? false : true;
}

bool Process_setPriority(Process* this, int priority) {
   int old_prio = getpriority(PRIO_PROCESS, this->pid);
   int err = setpriority(PRIO_PROCESS, this->pid, priority);
   if (err == 0 && old_prio != getpriority(PRIO_PROCESS, this->pid)) {
      this->nice = priority;
   }
   return (err == 0);
}

bool Process_changePriorityBy(Process* this, size_t delta) {
   return Process_setPriority(this, this->nice + delta);
}

IOPriority Process_updateIOPriority(Process* this) {
   IOPriority ioprio = syscall(SYS_ioprio_get, IOPRIO_WHO_PROCESS, this->pid);
   this->ioPriority = ioprio;
   return ioprio;
}

bool Process_setIOPriority(Process* this, IOPriority ioprio) {
   syscall(SYS_ioprio_set, IOPRIO_WHO_PROCESS, this->pid, ioprio);
   return (Process_updateIOPriority(this) == ioprio);
}

/*
[1] Note that before kernel 2.6.26 a process that has not asked for
an io priority formally uses "none" as scheduling class, but the
io scheduler will treat such processes as if it were in the best
effort class. The priority within the best effort class will  be
dynamically  derived  from  the  cpu  nice level of the process:
io_priority = (cpu_nice + 20) / 5. -- From ionice(1) man page
*/
#define Process_effectiveIOPriority(p_) (IOPriority_class(p_->ioPriority) == IOPRIO_CLASS_NONE ? IOPriority_tuple(IOPRIO_CLASS_BE, (p_->nice + 20) / 5) : p_->ioPriority)

#ifdef HAVE_LIBHWLOC

Affinity* Process_getAffinity(Process* this) {
   hwloc_cpuset_t cpuset = hwloc_bitmap_alloc();
   bool ok = (hwloc_linux_get_tid_cpubind(this->pl->topology, this->pid, cpuset) == 0);
   Affinity* affinity = NULL;
   if (ok) {
      affinity = Affinity_new();
      if (hwloc_bitmap_last(cpuset) == -1) {
         for (int i = 0; i < this->pl->cpuCount; i++) {
            Affinity_add(affinity, i);
         }
      } else {
         unsigned int id;
         hwloc_bitmap_foreach_begin(id, cpuset);
            Affinity_add(affinity, id);
         hwloc_bitmap_foreach_end();
      }
   }
   hwloc_bitmap_free(cpuset);
   return affinity;
}

bool Process_setAffinity(Process* this, Affinity* affinity) {
   hwloc_cpuset_t cpuset = hwloc_bitmap_alloc();
   for (int i = 0; i < affinity->used; i++) {
      hwloc_bitmap_set(cpuset, affinity->cpus[i]);
   }
   bool ok = (hwloc_linux_set_tid_cpubind(this->pl->topology, this->pid, cpuset) == 0);
   hwloc_bitmap_free(cpuset);
   return ok;
}

#elif HAVE_NATIVE_AFFINITY

Affinity* Process_getAffinity(Process* this) {
   cpu_set_t cpuset;
   bool ok = (sched_getaffinity(this->pid, sizeof(cpu_set_t), &cpuset) == 0);
   if (!ok) return NULL;
   Affinity* affinity = Affinity_new();
   for (int i = 0; i < this->pl->cpuCount; i++) {
      if (CPU_ISSET(i, &cpuset))
         Affinity_add(affinity, i);
   }
   return affinity;
}

bool Process_setAffinity(Process* this, Affinity* affinity) {
   cpu_set_t cpuset;
   CPU_ZERO(&cpuset);
   for (int i = 0; i < affinity->used; i++) {
      CPU_SET(affinity->cpus[i], &cpuset);
   }
   bool ok = (sched_setaffinity(this->pid, sizeof(unsigned long), &cpuset) == 0);
   return ok;
}

#endif

void Process_sendSignal(Process* this, size_t sgn) {
   kill(this->pid, (int) sgn);
}

int Process_pidCompare(const void* v1, const void* v2) {
   Process* p1 = (Process*)v1;
   Process* p2 = (Process*)v2;
   return (p1->pid - p2->pid);
}

int Process_compare(const void* v1, const void* v2) {
   Process *p1, *p2;
   ProcessList *pl = ((Process*)v1)->pl;
   if (pl->direction == 1) {
      p1 = (Process*)v1;
      p2 = (Process*)v2;
   } else {
      p2 = (Process*)v1;
      p1 = (Process*)v2;
   }
   long long diff;
   switch (pl->sortKey) {
   case PID:
      return (p1->pid - p2->pid);
   case PPID:
      return (p1->ppid - p2->ppid);
   case USER:
      return strcmp(p1->user ? p1->user : "", p2->user ? p2->user : "");
   case PRIORITY:
      return (p1->priority - p2->priority);
   case PROCESSOR:
      return (p1->processor - p2->processor);
   case SESSION:
      return (p1->session - p2->session);
   case STATE:
      return (p1->state - p2->state);
   case NICE:
      return (p1->nice - p2->nice);
   case M_DRS:
      return (p2->m_drs - p1->m_drs);
   case M_DT:
      return (p2->m_dt - p1->m_dt);
   case M_LRS:
      return (p2->m_lrs - p1->m_lrs);
   case M_TRS:
      return (p2->m_trs - p1->m_trs);
   case M_SIZE:
      return (p2->m_size - p1->m_size);
   case M_RESIDENT:
      return (p2->m_resident - p1->m_resident);
   case M_SHARE:
      return (p2->m_share - p1->m_share);
   case PERCENT_CPU:
      return (p2->percent_cpu > p1->percent_cpu ? 1 : -1);
   case PERCENT_MEM:
      return (p2->m_resident - p1->m_resident);
   case UTIME:
      return (p2->utime - p1->utime);
   case STIME:
      return (p2->stime - p1->stime);
   case TIME:
      return ((p2->utime+p2->stime) - (p1->utime+p1->stime));
   case COMM:
      return strcmp(p1->comm, p2->comm);
   case NLWP:
      return (p1->nlwp - p2->nlwp);
   case STARTTIME: {
      if (p1->starttime_ctime == p2->starttime_ctime)
         return (p1->pid - p2->pid);
      else
         return (p1->starttime_ctime - p2->starttime_ctime);
   }
   #ifdef HAVE_OPENVZ
   case CTID:
      return (p1->ctid - p2->ctid);
   case VPID:
      return (p1->vpid - p2->vpid);
   #endif
   #ifdef HAVE_VSERVER
   case VXID:
      return (p1->vxid - p2->vxid);
   #endif
   #ifdef HAVE_TASKSTATS
   case RCHAR:  diff = p2->io_rchar - p1->io_rchar; goto test_diff;
   case WCHAR:  diff = p2->io_wchar - p1->io_wchar; goto test_diff;
   case SYSCR:  diff = p2->io_syscr - p1->io_syscr; goto test_diff;
   case SYSCW:  diff = p2->io_syscw - p1->io_syscw; goto test_diff;
   case RBYTES: diff = p2->io_read_bytes - p1->io_read_bytes; goto test_diff;
   case WBYTES: diff = p2->io_write_bytes - p1->io_write_bytes; goto test_diff;
   case CNCLWB: diff = p2->io_cancelled_write_bytes - p1->io_cancelled_write_bytes; goto test_diff;
   case IO_READ_RATE:  diff = p2->io_rate_read_bps - p1->io_rate_read_bps; goto test_diff;
   case IO_WRITE_RATE: diff = p2->io_rate_write_bps - p1->io_rate_write_bps; goto test_diff;
   case IO_RATE: diff = (p2->io_rate_read_bps + p2->io_rate_write_bps) - (p1->io_rate_read_bps + p1->io_rate_write_bps); goto test_diff;
   #endif
   #ifdef HAVE_CGROUP
   case CGROUP:
      return strcmp(p1->cgroup ? p1->cgroup : "", p2->cgroup ? p2->cgroup : "");
   #endif
   case IO_PRIORITY:
      return Process_effectiveIOPriority(p1) - Process_effectiveIOPriority(p2);
   default:
      return (p1->pid - p2->pid);
   }
   test_diff:
   return (diff > 0) ? 1 : (diff < 0 ? -1 : 0);
}

redpajama_set_name: RedPajamaGithub


text:
Eagles to play New York Jets in 2021 as regular season expands to 17 games
Chris McPherson
Get ready for an additional week of regular-season football in 2021 as NFL clubs today approved an enhanced season structure that will feature each team playing 17 regular-season games and three preseason games for the first time.
It's the first time that the regular season has been altered since 1978 when the league expanded from 14 regular-season games to 16. There will still be only one bye week. The 2021 regular season will kick off Thursday, September 9 and conclude January 9, 2022.
For the Eagles, this means that they will now add a road trip to the New York Jets this upcoming season. The dates and times for the 2021 schedule will be announced later this spring.
"This is a monumental moment in NFL history," said NFL Commissioner Roger Goodell in a statement. "The CBA with the players and the recently completed media agreements provide the foundation for us to enhance the quality of the NFL experience for our fans. And one of the benefits of each team playing 17 regular-season games is the ability for us to continue to grow our game around the world."
Here is a look at the teams that the Eagles will play in 2021:
• Dallas Cowboys
• New York Giants
• Washington Football Team
• Kansas City Chiefs
• Los Angeles Chargers
• New Orleans Saints
• San Francisco 49ers
• Tampa Bay Buccaneers
• Atlanta Falcons
• Carolina Panthers
• Denver Broncos
• Detroit Lions
• Las Vegas Raiders
• New York Jets

redpajama_set_name: RedPajamaCommonCrawl


Refined, edgy, contemporary jewelry for everyday wear inspired by a love for travel.
Ashley Schenkein jewelry balances the beauty of refined details with an undeniable edginess. The use of asymmetry is evident in her creations that are both durable and timeless without compromising femininity. ASJD features contemporary jewelry for everyday wear inspired by Schenkein's love for travel.


text:
package io.crate.auth;

public enum Protocol {

    POSTGRES("pg"),
    HTTP("http");

    private final String protocolName;

    Protocol(String protocolName) {
        this.protocolName = protocolName;
    }

    @Override
    public String toString() {
        return protocolName;
    }
}


United States Congressional oversight in priorities and funding of the Administration's 2012 10.4 Billion dollar request for Missile Defense should focus on the missile defense capability required to deter the adversary and protect the U.S. homeland, U.S. armed forces overseas and allies, particularly Israel, against a possible first barrage of ballistic missiles from Iran, North Korea and emerging threats. Strategic, regional and tactical level defenses require three completely integrated joint architecture components of sensors, shooters and fire control and must have the war fighters' full confidence. In addition to protecting our most critical assets, operationally proven, tested, integrated and deployed missile defense systems serve as a significant deterrent to our adversaries and strengthen alliance cooperation which, in turn, invites burden sharing of costs.
Testing must be robust, operationally realistic and frequent across all systems to verify system performance and capability. Testing provides verifiable confidence for our nation's war fighters and political leaders. Testing also sends a strong message to our adversaries about our missile defense capabilities. It is troubling that MDA's 2012 test budget has again been significantly reduced, as has the number of scheduled tests. These two factors reduce our nation's missile defense credibility at home and abroad.
We must create conditions which allow integration between different systems and across the spectrum to occur during the acquisition process and not after the systems are fielded and deployed. It does not require significant funding to require integration in the development and acquisition phase. It is, however, costly and inefficient for the war fighter and the tax payers to sub-optimize our missile defense systems because we cannot integrate the best sensor information with the best interceptor available to counter the threat. Today, most of our deployed missile defense systems lack full joint integration at the strategic, regional and tactical level. A Joint Integration Missile Defense Center of Excellence is needed for STRATCOM, JFCC-IMD and the GCCs in order to advance missile defense operations and to ensure our war fighters at the highest levels are completely knowledgeable to make the best decisions for our nation and our allies.
Increasing production capability of deployed interceptors, launch platforms and sensors to reduce known capability gaps is critically important to our nation's war fighters. This will create stability and safety in crisis areas of the Persian Gulf, Israel and Korea as well as the homeland. Upgrading, where applicable, the sensor, processor, and interceptor systems to create more capability and more confidence for the war fighter is a very efficient use of tax dollars.
Request equal sensor architecture in both quantity and quality to include upgrades, integration and deployment of an East Coast X Band fire control radar for full protection against ballistic missiles launched from the Middle East to the Eastern United States that mirrors the capability currently in place today for the Western United States from North Korea. Fix and test with urgency the Exo-atmospheric Kill Vehicles (EKVs) on all Ground-Based Interceptors (GBIs). Upgrade and test with urgency the Sea Based X Band radar. Currently, the next GBI intercept test will occur no earlier than 18 months from today. That is too long and erodes the war fighter's confidence. If this system is not modernized in the next four years, it will be perceived as a "hollow�? force. Request a realistic hedge strategy for a 2nd shot "look-shoot-look-shoot�? capability to defend all of the Eastern U.S from an Iranian Long Range Ballistic Missile prior to 2020.
Increase the bipartisan political resolve for full support of NATO unification on the President's European Missile Defense from increasing Russian criticism against deployment of U.S. Missile Defenses in Europe. Complete deployment of Phase 1 of the PAA and ensure funding and support are in place for the testing, development and deployment of Aegis 4.0.1/5.0, Aegis Ashore, SM3 Block 1B and Block 2A for phase 2 of the PAA. Ensure support for persistent forward based sensor integration, testing, development and deployment of ABIR platforms, STSS next generation and upgraded AN/TYP-2 with Aegis to engage and launch on remote. Add an additional U.S Army ADA Battalion and an AAMDC Flag to European Command to provide it similar missile defense capabilities as CENTCOM and PACOM. These forces will directly assist in defending Israel better as well as help protect the force and add robustness to the deployed phases of PAA.


text:
BLOG --> MT SKIM
TOP MT JOBS
Our Blog > MT Business Roundup
Innovate Montana Symposium taking place in Billings, Montana leads the country in entrepreneurship, Bozeman Health Deaconess Hospital receives national recognition, MetraPark visitors pumped $151M into Billings economy last year...and more
Montana leads the country in entrepreneurship, UM study says
According to a new study by the University of Montana's Bureau of Business and Economic Research, Montana leads the country in entrepreneurship. The results of the study were shared by Bryce Ward at the Montana Chamber of Commerce's Annual Economic Update Series, which kicked off this past Thursday, August 2, in Kalispell. Ward found that in 2015, more than 10 percent of Montanans owned a business as their primary job, compared to six percent of Americans. He also found that about 3,400 Montanans start a new business each month, and that more than half of the startups formed in 2011 were still open for business five years later. Ward says this implies a healthy entrepreneurial ecosystem. But unlike elsewhere in the country, startups in Montana tend to stay small. In fact, the average size of a new firm is the lowest nationwide, with an average of three employees, compared to the national average of six. The Montana Chamber of Commerce's Economic Update Series moved across the state all week hitting Glasgow, Sydney, Billings, Bozeman, Butte, Helena, Great Falls and wrapping up in Missoula. [Montana PBR]
Innovate Montana Symposium taking place in Billings
The Third Annual Innovate Montana Symposium is taking place today (August 9) in downtown Billings. The event, which was created to help Montana's entrepreneurs grow wages and create top Montana jobs, looks to foster entrepreneurship and build business relationships across our state. An impressive list of speakers and panelists are expected at the event, including angel and venture investors, the former lead of Google Maps, the founder of multiple highly successful outdoor recreation manufacturing businesses, the founder of one of Montana's top breweries, many other CEOs and c-level executives, and Governor Bullock. [Innovate Montana Symposium]
DermaXon: Missoula startup receives $99K grant to research med for chronic pain
Missoula upstart biotech company DermaXon was recently awarded a grant from the Montana Department of Commerce to help fund more studies and generate data needed to attract investors for a new compound to treat chronic neuropathic pain. The $99,326 grant from the Montana Board of Research and Commercialization Technology (MBRCT) will help finance further research and development of the topical treatment. Data generated by the research will help attract investors and grants from the government. DermaXon founders Fanny Astruc-Diaz and Philippe Diaz can then begin clinical trials for the medication to gain approval by the FDA, allowing sales nationwide. According to the Missoula Economic Partnership, biotech is a developing and thriving industry in Missoula. However, biotech has faced challenges finding a local workforce for the industry. DermaXon recently hired CEO Michelle Huie, who founded VIM & VIGR (hiring) in Missoula, as well as a recent University of Montana graduate. The company has said it is happy to be a future employer for those who study biology and chemistry at the University of Montana. [Missoula Current]
Alchemy Systems (which acquired Wisetail in Bozeman) to sell to Intertek Group for $480 million
Alchemy Systems, which acquired Wisetail in Bozeman, has agreed to be acquired by London-based Intertek Group in a $480 million all-cash deal. The Austin company employs about 270 people in four U.S. offices and makes software to monitor and train workforces in the food sector. The deal is expected to close in the third quarter. Intertek's announcement of the buyout, which includes details such as transaction and financial highlights, can be found here. [Austin Business Journal]
Missoula tech company aimed at tourism industry marks 18-month growth
When an upstart Missoula tech company won the Montana Shark Tank pitch competition last year, its founder was happy to take home the $5,000 prize. Now, Evan Tipton, founder and CEO of TOMIS (hiring), has set his sights on loftier financial goals. The company plans to launch a bridge to Series A investment round to raise $3 million in capital this year which Tipton says would be to "beef up our product development and implement our data science and customer support team." In simple terms, TOMIS provides digital marketing assistance for tour operations. The product integrates and analyzes marketing and sales data which is then placed against an algorithm that tells clients in the tourism industry when to act, how to act and how much they'll make if they follow suit. TOMIS opened its office in downtown Missoula just 18 months ago and has seen tremendous growth in that time with a team of nearly 30 today. A year from now, Tipton said, the company looks to have a new Missoula office, grow to 50 employees and serve as the leading marketing platform in the tours and activities space. [Missoula Current]
Polson-based Black Mountain Software celebrates 30 years
Black Mountain Software, a Polson-based company that creates accounting software for municipalities, counties and school districts in small- to mid-sized towns, is celebrating 30 years in business (and they are also hiring). President Heather Neff has been with the company for 20 years. She said a lot has changed in the software industry and in their business during that time. And while Polson isn't necessarily thought of as a hotbed for tech companies, Neff said being located in a town of similar size to those they service makes sense and has been a natural fit. Since its beginning in the early 90s, the company has seen steady growth, adding two to three employees each year to accommodate a client base that expands by 20 to 30. Additionally, Neff said maintaining the qualities that made them attractive as a small-town company despite their growth has been critical to its success - hiring applicants with promising character traits over existing knowledge bases or skill sets because even as technology advances, those traits remain relevant. [Daily Inter Lake]
With $50K on the line, Missoula tech company Superior Traffic Services hones business plan at accelerator
A Missoula tech firm, Superior Traffic Services, participated alongside six other startups from across the state in the inaugural HpyerAccelerator program hosted by Early Stage MT, in which the business received an intense 50-hour program to help enhance their business plans and explore ways to finance their growth. According to Superior Traffic Services CEO, Jeff Hollenback, "We got a lot out of it, and it was really insightful. We went in with a business plan that was pretty conservative. It exceeded my expectations, really." The company will advance next month as one of the seven companies to compete for a $50,000 equity investment offered by the Frontier Angels fund. [Missoula Current]
Bozeman Health Deaconess Hospital receives national recognition
Bozeman Health (hiring) recently announced some impressive milestones. Bozeman Health Deaconess Hospital was named as a Top 20 Rural & Community Hospitals for 2018 by iVantage and included in Becker's Hospital Review Top 100 Community Hospital's List. Further, Bozeman Health president and CEO John Hill has been recognized as a "Rural Hospital CEO to Know" by Becker's Hospital Review. All are prestigious recognitions. The iVantage Health Analytics' Hospital Strength INDEX® is the industry's most comprehensive and objective assessment of rural provider performance. Its results are the basis for many of rural healthcare's most prominent awards, advocacy efforts, and legislative initiatives. The Top 100 Rural & Community Hospitals play a key role in providing a safety net to communities across America. The INDEX measures these facilities across eight pillars of hospital strength: Inpatient Share Ranking, Outpatient Share Ranking, Cost, Charge, Quality, Outcomes, Patient Perspective, and Financial Stability. Additionally, CEO John Hill was recognized in Becker's Hospital Review 50 Rural Hospital CEOs to Know for 2018, the second consecutive year John has received this recognition. According to Becker's, the CEOs featured on this list have overcome significant challenges operating rural community and critical access hospitals to lead sustainable and thriving organizations. [Bozeman Health]
Libby is Montana's 'Most Charming Small Town,' says Reader's Digest
Libby is the most charming small town in Montana, according to Reader's Digest. The publication from July posted a list outlining "The Most Charming Small Town in Every State." The paragraph accompanying the Libby entry highlights its view of the Cabinet Mountains and its proximity to outdoor recreation. It also calls out two local businesses "for a local's experience" — Cabinet Mountain Brewing Company and The Black Board Bistro. Local economic developers see the accolade as both a reaffirmation of and a potential boost to existing efforts to attract people and commerce to the town. The full article can be found online here. [The Western News]
ClassPass to expand to First Interstate Center, looks to add 40 more high-paying Montana jobs
The fast-growing tech company, ClassPass (hiring in Missoula) recently announced it will be expanding to the fifth floor of the First Interstate Bank building in downtown Missoula and has signed an agreement with Missoula County to create another 40 high-paying Montana jobs in addition to the 70 new jobs it's already created in Missoula. Almost all of ClassPass's customers are located outside of Montana, so the employees at the Missoula office bring in new revenue to the local economy. When the company first opened its Missoula office, it originally applied for $345,000 in Big Sky Economic Development Trust Fund grant funds to create 45 new Montana jobs. Nicole Rush, the grants administrator for the Missoula Economic Partnership, said the company's growth has been beyond original expectations. "They have actually already hired more than 70 employees at their Missoula office, so well above the grant target for job creation," she said. [Missoulian]
Montana Made: The Oil Barn (in Big Sandy, MT)
A business near Big Sandy, Montana, called The Oil Barn has found a number of ways to utilize its product. The Oil Barn has been producing safflower oil since 2011. And according to manager Trevor Wilkerson, what started out as a biodiesel operation soon turned into an opportunity to produce safflower oil for consumption. "That's when they found a deli that also wanted to use it in their fryers…decided they could turn more of a profit in the fryers but could also reclaim that and reuse it in tractors after they'd clean it," Wilkerson said. It's now a developed process that benefits both the farming and food industries. While their oil is shipped worldwide, The Oil Barn also gets plenty of business in the Treasure State. They work with Montana State University and the University of Montana and also have their product in a number of grocery stores and delis. Wilkerson says the production of safflower oil has even given the local economy a boost and has the potential to bring more jobs and more industry to Big Sandy. [KRTV]
MetraPark visitors pumped $151M into Billings economy last year, report shows
A new independent study, funded by NorthWestern Energy, shows that MetraPark has a $150.9 million annual impact on the local economy. Rob Gilmore, the CEO of Circle Analytics, which conducted the study, presented his findings to the Yellowstone County Board of Commissioners this week. Gilmore said the $150.9 million figure measures the financial impact provided by only the approximate 296,000 MetraPark visitors that came from outside the area during 2017. Of the $150.9 million, $87.8 million is what Gilmore labeled the gross county product — the sum of labor compensation, capital-type income and indirect business taxes and fees, which amounted to about $10.8 million. Total labor income (i.e. compensation to employees and self-employed proprietors, including retirement benefits and health insurance) was $52.2 million. The number of Montana jobs generated as a result of MetraPark's operation was 2,023. "We knew that MetraPark is an economic driver in this community and is a huge benefit," said Patrick Klugman, senior project manager with Big Sky Economic Development, who helped coordinate the reporting involved with the study. [Billings Gazette]
Montana product, from Missoula-based Reflex Protect, could protect kids from active shooters at schools
With the school year around the corner, a Missoula-based start-up, Reflex Protect, is working to get their invention in classrooms across Montana. The company has created a non-lethal product that has said to be more effective than pepper spray when it comes to stopping an active shooter. Reflex Protect CEO Joe Anderson says not only can Reflex Protect help in active shooter situations in schools, they also have a version for hospitals. Providence St. Patrick Hospital in Missoula already keeps some of the spray on hand. Anderson says the hospital version is easier to clean up after being used, so hospitals can quickly clean up and continue caring for patients. He believes the spray is "a good alternative to a loaded handgun in a nightstand drawer." Reflex Protect is in contact with Hellgate Elementary in Missoula and the Polson school district. They say the schools will be test implementing Reflex Protect in August. [ABC Fox Montana]
Blog + Montana Business News
© 2019 The Work Spot, LLC


text:
Do social crises lead to religious revivals? Nah!
5 years ago in Epiphenom
22 health lessons from "Trust me, I'm a Doctor"
7 years ago in The Allotrope
There's a Hole in the Bottom of the Sea
By Elizabeth Preston on Tuesday, March 29, 2011
"There's! A! Flea, on the fly, on the wart, on the frog, on the bump, on the log--" Does anyone else remember this song? Because it has been going through my head ever since I started reading about the human virome. That's the viruses that live inside the bacteria that live inside us.
First there was the genome--all the DNA in a human--which we've now got a pretty good handle on. It turned out that our smallish number of genes can be shuffled into a larger number of RNA "transcripts," so there's also the transcriptome. Those transcripts are used to make the proteins in our body, naturally known as the proteome. The microbiome is all of the microorganisms that live inside humans. (Don't look now, but there are 10 times more of their cells than yours in your body.) And the virome goes a step more microscopic, to the viruses.
The bacteria inside us have been the subject of a lot of interesting research lately. They occupy us as paying tenants, helping to digest our food and performing other mysterious functions that seem to maintain our good health. Existing around and in those bacteria are viruses that vastly outnumber even the bacterial cells.
Some scientists are starting to explore the role these viruses play in our bodies. At Washington University in St. Louis, Jeffrey Gordon and his colleagues studied the viruses inhabiting four sets of adult identical twins and their mothers. (They did this by sequencing the viral genes in their stool samples.) Previous studies had shown that twins and their mothers have more similar bacterial populations than unrelated people do. Surprisingly, though, there was no such connection between the viral populations--people have unique viromes, regardless of how related they are.
But the viral populations seemed to be stable. In three samples taken over the course of a year, the subjects' viromes were consistent. So the differences between people aren't due to a constant turnover in the types of viruses they harbor.
Furthermore, Gordon found evidence that the bacteria and the viruses that attack them (called phages) were coexisting relatively peacefully, and not engaging in the turf war that might be expected.
So what are they doing in there? Are they helping us? Hurting? Neither or both? Gordon suggests that studies of the human microbiome should include the virome, so we can find out.
One interesting preliminary result has come from another set of researchers at Washington University who are studying viruses in babies. Looking at the viral genes in babies' nasal samples, they compared healthy babies to babies with unexplained fevers. They say they found 10 times more viruses in the feverish babies. It's not clear whether the viruses are to blame for the fevers or something more complicated is going on. But if doctors learn that the virome is to blame in these cases, they could avoid prescribing unnecessary antibiotics (since antibiotics only treat bacterial infections).
It's good to avoid unnecessary antibiotic use, of course, because it encourages bacteria to develop resistance to those drugs. That brings up another point about the virome: Phages, the viruses that prey on bacteria, sometimes drag bacterial genes between their victims. A gene for antibiotic resistance, for example, could be spread among a population of bacteria in your body by the viruses there.
More alarming and interesting relationships will, no doubt, emerge as scientists continue to learn about the microscopic menageries inside us. I just hope they don't find any more "omes." Really, it's enough already.
Labels: medicine, microbiome, things with only one cell
A Cloud and a Silver Lining, Part II
By Elizabeth Preston on Friday, March 25, 2011
Last week, things were looking pretty bad at the Fukushima Daiichi nuclear power plant in Japan. (See the first installment of "A Cloud and a Silver Lining" here.) Since then, helicopters and firehoses have intervened, spinach and drinking water have caused concerns, and things are looking...still pretty bad.
Keeping the fuel in the reactors cool, as well as the used fuel rods that are stored in pools of water, is crucial to preventing radiation from leaking out. Heat from the fuel rods makes water boil off of them, so it has to be constantly replaced. Helicopters were used last week to dump water into the spent fuel pools from above, while firehoses sprayed water onto the reactors. Early this week, workers were finally able to string power cables to the plant's six reactors, restoring electricity. That meant the cooling systems (at least, their non-damaged components) could be turned back on, though workers would still have to fight to clean up the radioactive material and stop the leaks.
Then radioactive iodine showed up in Tokyo's tap water. The levels weren't dangerous for adults, but the government urged parents not to let babies drink any tap water--since their thyroid glands are still developing, they're more liable to absorb the cancer-causing isotope. Radioactive iodine and cesium have also turned up in milk and vegetables (such as spinach) around Fukushima. Japan has banned the sale of these products, and the United States has stopped importing dairy and produce from the region. Luckily, the radioactive iodine has a half-life of just 8 days, so it won't stick around for very long--once it stops coming out of the nuclear plant, that is. But the radioactive cesium has a half-life of 30 years. This means its presence in farmlands could become a very long-term problem.
Differing evacuation recommendations from the Japanese and American governments have caused confusion and tension. The Japanese government ordered a total evacuation within 20 kilometers (12 miles) of the plant, and told people between 20 and 30 kilometers away to stay indoors. Meanwhile, the U.S. government urged its citizens in Japan to stay 50 miles away from the plant. The Nuclear Regulatory Commission's reasons for the 50-mile recommendation were somewhat unclear, since the radiation reaching that far from the plant is, so far, negligible. But the NRC may have been betting against Japan's ability to subdue the growing nuclear crisis.
Today, the Japanese government seemed to similarly lose confidence, widening the evacuation zone to 30 kilometers (19 miles). Those residents aren't being ordered to leave--though, after staying indoors all this time, they might be happy to. A new concern is that one building's reactor vessel may be leaking radioactive material. Two workers suffered radiation burns from water that sloshed into their boots near the reactor. An anonymous nuclear executive told the New York Times that the vessel has a "definite crack."
So where's the silver lining? Radiation levels in the Tokyo tap water dropped, making it safe for infants again. And though the Japanese government has been less than transparent about the situation at Fukushima Daiichi, people have begun gathering and distributing information on their own. Several sites are using crowd-sourced data to create maps of the radiation in Japan. This site uses Google Earth to map radiation levels, which puts the disaster into beautiful perspective even as it continues to unfold.
Labels: whether to panic
Wrinkly Dog Syndrome
To say that the Shar-pei is a wrinkly dog is putting it mildly. The ones that have been bred in China for hundreds of years are identifiable by a furrowed brow that makes them look permanently concerned (D). The Shar-Pei dogs bred in the West, though (A-C), have been turned into baggy overgrown puppies that can barely see you from behind their folded-up faces.
Like other purebreds, the Shar-Pei has health problems. Some of them are symptoms of its desired traits (such as a susceptibility to infections inside its skin folds), while others are genetic accidents that come from generations of inbreeding and artificial selection. A condition called Familial Shar-Pei Fever (FSF) is one of those genetic disorders. But a new study has shown that, rather than being a genetic fluke, FSF comes from the very same mutation that causes the dogs' wrinkliness. The disease has been bred into them along with their cute, scrunchy faces.
Researchers in Sweden (one of whom is named, improbably, Puppo) compared the DNA of a group of Shar-Pei dogs to dogs of other breeds. They found a pronounced difference on chromosome 13, in the genetic region that makes a gooey molecule called hyaluronic acid (HA). This was no great surprise: the Shar-Pei's thick and wrinkled hide is known to be caused by a huge buildup of HA in the skin.
The surprise came when the researchers divided up the Shar-Pei group into those affected and unaffected by FSF. The disorder causes frequent fevers and inflammation. Scanning the genome for a region associated with the disorder, the researchers found themselves right back at chromosome 13. The wrinkly-skin mutation is a duplication--a certain chunk of DNA copied one or more times. The dogs had varying numbers of duplications, like a stutter in this genetic region. And the scientists saw that the dogs with the most copies were the most likely to have the fever disorder.
So the very trait that breeders have valued in the Shar-Pei is what makes it ill. The problem may arise from broken fragments of HA molecules, which might encourage inflammation. The authors speculate that excess HA might be responsible for even more of the Shar-Pei's health problems, such as skin allergies, tumors, and kidney damage.
But the good news is that the wrinkly dogs might be able to help humans. Some people suffer from inherited fever syndromes that are similar to FSF. A few genetic links have been found, but about 60% of these cases have no known cause. Future research might find a link between hyaluronic acid and chronic fever disorders in humans, leading to new treatment possibilities. Of course, the best treatment for the Shar-Pei would be to stop breeding it. But as long as people keep demanding squishy-looking pets, that seems unlikely.
Image: PLoS Genetics/doi:10.1371/journal.pgen.1001332.g001
Labels: cats and dogs, genes, medicine
The Japanese Blues
By Elizabeth Preston on Saturday, March 19, 2011
You've seen those posters in the subway: "If You See Something, Say Something." It sounds like a reasonable summation of how language works. First we see something, then we connect it to the right word or words in our mind, and then we are able to say something about it. But can it also work backward?
Some scientists think that how we talk about a thing can influence how we perceive it. An easy way to test this is with colors, and studies in the past have shown that people are more likely to see two colors as similar if their language groups those colors together under one name. If there are more names for colors, people may be better able to tell the difference between them.
In Japanese, there are two words for blue: ao is darker blue and mizuiro is lighter blue. (These are just the common, one-name terms; obviously any English speaker with a Crayola box could come up with a dozen kinds of blue. But you're unlikely to categorize something as "cornflower" or "cerulean.")
Linguist Panos Athanasopoulos and his colleagues wanted to know if Japanese-English bilinguals would perceive blues more like English speakers or more like Japanese speakers. Would they understand blue as two colors, or one? To test this, they gathered 27 bilinguals, all native Japanese speakers who were college or graduate students in the UK. They also recruited 27 monolingual subjects; half were English speakers, and the other half were Japanese students who had just arrived in the UK to begin studying English.
The subjects were shown pairs of blue squares with varying hues and asked how similar the two colors were (on a scale of 1 to 10). There were 10 different blues used in there experiment, and all of them had been consistently described as ao or mizuiro by Japanese speakers in a previous experiment. The researchers expected that in this experiment, Japanese speakers would see the pairs as less similar if one was ao and the other was mizuiro.
They found that English speakers, as expected, categorized their colors independently of whether they were ao or mizuiro. (So even though the two categories exist in Japanese, they're not inherent to how we see color.) Japanese monolinguals described dissimilar pairs of blues as even less similar if one was ao and the other was mizuiro. And the bilinguals were sort of in between: they were only slightly influenced by whether a color was ao or mizuiro. Learning English had apparently blurred the categories together in their perception. Analyzing their data further, the researchers found that among the bilinguals, those who had more experience in English increasingly ignored the ao/mizuiro distinction.
The researchers made sure gender wasn't affecting their results. In this country, men are notorious for not being able to distinguish between colors. Even if it's true, this study reminds us that a difference in perception doesn't necessarily come down to how well your eyes work. Maybe boys in America are taught not to enjoy all the cornflowers and ceruleans and forget-me-not blues, and as a result never learn to distinguish them.
"Language is the mechanism that assists the influence of culture on cognition," the authors write. That is, our vocabulary influences how we perceive the world, and that vocabulary comes from the culture we live in. In the weeks and years to come, we'll see how the Japanese translate their new blues into words. Not only can we not comprehend the loss the country experienced in the earthquake and tsunami, or the danger they feel from the ongoing nuclear crisis--but we wouldn't even experience it the same way if we were there.
Labels: boys and girls, brains, language
A Cloud and a Silver Lining
By Elizabeth Preston on Wednesday, March 16, 2011
For the past few days, the only science news I've been thinking about is happening in Japan.
There have been a few pleasant diversions: elephants that understand teamwork; whales that seem to address each other by name; office workers who boost their attention spans using houseplants. But the nuclear disaster seems more important to talk about right now.
In case you've missed it, the one-two punch of unprecedented earthquake and massive tsunami overwhelmed Japan's Fukushima Daiichi nuclear plant, which has six nuclear reactors. Though the reactors automatically shut down in the earthquake, a series of explosions, fires, and leaks has kept workers racing to prevent a large-scale release of radiation. To compensate for failed cooling systems and prevent reactors from melting down, workers have been pumping in seawater, which constantly boils away. Also of concern are pools at the top of each reactor that hold used-up fuel rods to cool for many years. If these pools boil dry, the old fuel could catch fire and release radioactive material.
750 workers were evacuated from the plant on Tuesday because of the high levels of radiation there. A skeleton crew of just 50 workers stayed behind to try to prevent a larger disaster. (In order to keep the skeleton crew at the plant, the Japanese government raised the legal limit on radiation exposure for workers.) That number may have now been increased to 100 people.
Accurate information has been hard to come by. Last night, a Japanese official giving a press conference announced (via a translation that seemed pretty approximate) that all workers had been evacuated from the plant. This seemed to imply, grimly, that they were giving up on containing the radiation--until the Times reported that the small crew of workers was, in fact, still at the plant trying to cool things down.
There is some good news. If large amounts of radiation are released, the Japanese government is prepared with potassium iodide pills. These pills flood the body with iodine so the thyroid gland doesn't absorb any radioactive iodine, leading to thyroid cancer. (An epidemic of thyroid cancer was the legacy of Chernobyl.)
Additionally, radiation is expected to blow east. That means this developing disaster has a greater buffer zone--the entire Pacific--than it would probably anywhere else in the world.
For answers to all kinds of questions on this subject as they arise, check out ScienceInsider or the New York Times.
Trust Your Gut
At Washington University in St. Louis, researchers have found that humans' ability to survive starvation may depend on the kinds of bacteria living in their guts. They deduced this by feeding poop and peanut butter to mice.
How about I back up a little.
If you haven't heard, the hot new field in biology is the "microbiome." There's even a Human Microbiome Project, started in 2008. It's reminiscent of the Human Genome Project, which pushed through the 1990s and early 2000s to complete a sequence of the human genome. But the microbiome isn't made of human DNA, or human anything. It's the collection of bacteria and other microorganisms that live inside us. And it's starting to seem pretty important.
Your microbiome is not an everyday cold or patch of infection. It's the Alamo. For every single cell in your body, there are 10 microbial cells. Yes, in your body. The only reason you look like a person and not a big oozing blob is that your cells are way bigger. Most of these microbes live in a thick layer in your intestines, where they help you digest certain foods but otherwise stay out of your business. In addition to the gut, your microbial companions (also called, rather romantically, your "flora") live in your various orifices and all over your skin.
Microbes first colonize humans at the moment of our birth. But our microbial populations can change over time: we eat things, touch things, get sick, take antibiotics. Scientists are just beginning to understand the relationship between our gut flora and our overall health. It's not a trivial relationship; we've evolved with this population as a part of our bodies.
The researchers in St. Louis are studying the role of gut bacteria in malnutrition. Specifically, they're looking at twins growing up near-starving in Malawi. Even though they have the same genes and eat the same food (what there is of it, anyway), the twins sometimes respond differently. One twin may develop kwashiorkor, the bloated-belly form of malnutrition that we see in photos from impoverished countries, while the other twin doesn't.
As ScienceNOW reports, the scientists wondered if different gut bacteria might be responsible for different responses to malnutrition. To test their theory, they took stool samples from a pair of twins like those described above. They fed the two stool samples to two groups of mice that had been carefully kept sterile since birth, in order to colonize the mice with the children's gut bacteria. Then they alternated between feeding the mice a typical Malawian diet (mostly corn flour) and a food used to treat malnutrition (which includes peanut butter).
The mice with the healthy twin's bacteria maintained a more stable weight, and a more stable population of gut flora, than the mice with the kwashiorkor twin's bacteria. Though this was just a pilot study, it suggests that gut bacteria may be crucial to humans' ability to survive starvation.
More applicable to most of us in the Western world was a 2009 study out of the same Washington University lab. Looking at gut microbes from obese and non-obese twins, the scientists found that the obese people had fewer types of bacteria in their guts. They also found that mothers and their children share a lot of their gut flora, regardless of whether the children are identical twins. This implies that our microbial makeup has much more to do with our environment than our genes.
In the future, doctors may use this kind of information to treat patients with microbial therapy--instead of drugs, why not put the right balance of bacteria into your body and let them do the work? Some doctors are already using so-called fecal transplants, which are exactly what they sound like. Is it gross? Yes. But pretty soon, we may have to get over it and admit that our microbes are looking out for us.
Mind-Control Fungi: You Can't Look Away
I wish I could tell you this is the rare Brazilian dead-eyed reindeer ant. But it's not. It's a regular dead ant with a parasitic fungus growing out of its head.
The fungus, in the genus Ophiocordyceps, didn't wait until the ant was dead to make a home inside its body. In fact, the fungus was the killer. When the ant was first infected with the fungus, it broke from its usual behaviors and climbed up to a high leaf. Then it clamped its jaws down, anchoring its body to the leaf, and died. Now in an advantageous spot for reproduction, the fungus sprouted a long, spore-bearing structure from the ant's head that will shower spores onto new ant prey below.
Parasitic fungi--even mind-controlling parasitic fungi--are nothing new to science. There are around 140 species in the Ophiocordyceps genus alone. What's new is that Penn State entomologist David Hughes and colleagues took a closer look at one species, Ophiocordyceps unilateralis, and discovered that it's actually, um, four species.
In the Brazilian rainforest, researchers collected infected carpenter ants (easily spotted by the filaments bursting out of their joints or stalks emerging from their heads).
On close inspection, they found that O. unilateralis could be divided into four clear subtypes with different appearances. They gave each type a new species name, and intend to study the fungal DNA to confirm the differences they found.
Since the four species showed up in different species of carpenter ants, Hughes writes, "It is tantalizing to speculate that each species...may be attacked by a distinct species of Ophiocordyceps." More research will be needed to show whether that's really true. As for the mind-controlling fungi that attack wasps, flies, and other insects, are they equally specialized? How many insect species have a dedicated parasitic-fungus species? There may be a whole world of fungi out there that have evolved in parallel to the insect world: an entire tree of life dedicated to getting inside other life-forms' heads.
That should give you something to think about. Just don't get the idea to climb up to a high branch and bite down.
Images: David Hughes
Labels: bugs, disease
Beating the Odds
Sometimes extinction can be a blessing. Aren't you glad this 500-million-year-old "walking cactus," for example, isn't alive today? It lived on the bottom of the ocean, to be fair. But just knowing it was there would have bothered me.
Conservationists have been speculating for years that we're in the midst of a mass extinction. In the planet's history, five of these events have occurred. To qualify, three-quarters of all species on Earth must be wiped out. The most recent mass extinction was the one that did in the dinosaurs. Prior to that, incidents such as global cooling or global warming served to wipe out huge numbers of species. And before any of those events, when the planet was occupied by simple single-celled creatures, the rise of the first photosynthesizers released oxygen into the atmosphere and destroyed most other forms of life.
So Earth is no stranger to slate-wiping events. But the great extinctions of the past occurred over hundreds of thousands, or millions, of years. Are humans, by spreading across every surface on Earth and pushing out the animals and plants that lie in our path, causing a new extinction event that's accelerated beyond anything the planet has seen before?
Anthony Barnosky, a paleobiologist at UC Berkeley, says yes. Barnosky and his colleagues compared the current rate of extinction among mammals to their historical extinction rate (since mammals are well catalogued today and well represented in the fossil record). They also examined the historical extinction rates of groups such as amphibians and birds that have been thoroughly assessed by the International Union for Conservation of Nature (IUCN), the group that labels species as endangered. Rates of extinction today, they found, are clearly higher than normal historic rates.
The researchers then compared all of these findings to the rates of species loss that drove the mass extinctions of the past. To project future extinctions, they looked at animals that are currently "threatened"--labeled by the IUCN as critically endangered, endangered, or vulnerable (more on that in a moment). If all threatened animals became extinct in the next hundred years, and we carried on at the same rate of species loss afterward, it would take between 240 and 540 years for 75% of species to be wiped out. That is, within just a few centuries, we could see a legitimate mass extinction.
The good news is that this outcome is far from certain. While a "critically endangered" species is defined as having only a 50% chance of surviving the next ten years--meaning its prospects for the coming century are pretty grim--a "vulnerable" species is considered to have only a 10% chance of extinction over the next hundred years. So for all currently threatened species to be gone within a hundred years would be, by the IUCN's definitions, very unlikely.
The point stands, though. Even if only the critically endangered animals disappear in the next hundred years, and if that rate continues, it will take some hundreds or thousands of years for us to reach the 75% mark--rather than the hundreds of thousands or millions of years seen in the five mass extinctions. This is species loss at a completely unnatural rate.
And it's our fault, in case you were unclear. The authors list changing atmospheric conditions, global warming, habitat loss, pollution, overhunting, overfishing, invasive species (carried by humans to places they don't belong) and "expanding human biomass" as reasons for the extinctions. The sheer weight of us on the world is, it seems, too much. But the future isn't certain. If we care enough, we might be able to beat the odds.
Image: Jianni Liu
Labels: ancient history, climate, whether to panic
Botswanavision
Do you ever find yourself squinting into the glare of your computer screen around 4 PM and thinking that your eyes aren't built for this? You're right, of course. The human eye evolved on the African savanna. This is what it's built to see:
Scientists from the University of Pennsylvania and elsewhere took about 5,000 digital photos in a Botswana savanna. They captured natural scenes at various times of day, from sun-baked vistas to up-close tree bark to fresh elephant dung, and compiled the images into a publicly available database.
Clicking through the albums may make you feel overheated, but it also simulates a pleasant stroll through the savanna. (Spoiler alert: baby baboons!)
The researchers used this database to investigate the evolution of the human eye. Specifically, they wanted to find the logic behind how our color-sensing machinery is set up.
Our eyes detect color using cone cells, which come in three types: one that detects light at short wavelengths (blue), one for medium wavelengths (green), and one for longer wavelengths (red). The three types of cones aren't distributed evenly across the retina, though. The blue-detecting cones are rare, and mostly exist around the outer edges of the retina. The red and green cones are much more common, but the ratio between them varies widely from person to person.
For each of the scenes in the Botswana photo database, scientists calculated how much light of different wavelengths would be reaching the viewer's eye. Based on those numbers, they mathematically determined the most efficient distribution of cone cells in the retina. They found that blue-detecting cones couldn't pick up as much information as the red or green cones (which explains why we don't make very many of these cells) but were most useful at the periphery of the eye. The red and green cone cells, though, would be about equally useful at picking up information from these scenes. That explains why humans can have widely varying ratios of red to green cone cells without an effect on their vision.
Though they may seem disorganized, our retinas have evolved to efficiently gather information from our environment--or our ancestral savanna, anyway. Future research might address how our eyes handle other environments. Additionally, the authors say that knowing how to build eyes efficiently might help us create better robots. Not having had the benefit of evolution, today's robots can't see nearly as well as we can.
Photos: University of Pennsylvania.
Labels: ancient history, apes
Who's Inkfish?
Hi, I'm Elizabeth. I live near Boston and work as the editor of MUSE, a kids' science magazine that's not otherwise related to this blog. My writing has also appeared in National Geographic, Slate, and other publications. Read more here.
If you like Inkfish, Like it on Facebook too!
Inkfish tweets.
Follow @Inkfish
Subscribe to Inkfish!
headline-itis
one funny thing
placebo/nocebo
posts that will bring me creepy internet traffic
screwups
shambulance
the outback
things with only one cell
weird animals
whether to panic
And for all this, nature is never spent; / There lives the dearest freshness deep down things
--Gerard Manley Hopkins
Latest From The Network...
about | contact | archives & alumni
subscribe: feed - email
follow: twitter - facebook - badge


On Thursday, Aug. 23, the State Objections Board put independent Greg Orman on the November ballot for governor. This decision cleaves a block of voters that Democrat Laura Kelly had hoped to secure against the alt-right Republican nominee, Secretary of State Kris Kobach.
The board, composed of the attorney general, secretary of state and the lieutenant governor, rules on official objections regarding candidates, ballots and other election issues. At the meeting board members were represented by proxies, among them Kobach's chief assistant, Eric Rucker.
The proxy board ruled that Orman had collected far more than the 5,000 signatures needed for his name to be on the Nov. 6 ballot. Democrats, with Kelly in mind, had objected; they claimed that thousands of signatures for Orman were invalid because they had been gathered by out-of-state contractors hired to circulate his ballot petitions.
An attorney representing Lt. Gov. Tracey Mann agreed with the Democrats. But Rucker, and a proxy for Attorney General Derek Schmidt, said the signatures were good. This was expected.
The setup could be seen for months, from the moment Orman said he wanted to run as an independent. At first, speculation had it that Orman might have a chance: Democrats but especially Republicans, wary of their own parties' nominees, would vote for the independent.
In Kansas, though, it won't happen. Independents make all Republicans nervous and most Democrats suspicious. They will stick with their own kind, if they stick with anyone, and the Objections Board knew it. Kobach could not be happier.
Orman may secure 12 or 15 percent of the vote, Kelly 35 or 40 percent. Kobach is likely to be elected — a minority governor — with roughly 45 percent. That's the plan, and the board was aware of it because Orman was not about to go away.
So the question this year is not who will win, but how the majority vote splits for the losers. What can be done about it?


text:
package org.jetbrains.idea.svn.ignore;

import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vcs.changes.ui.ChangesListView;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.JBIterable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnStatusUtil;
import org.jetbrains.idea.svn.SvnVcs;

import static com.intellij.util.ArrayUtil.isEmpty;

public class IgnoreGroupHelperAction {
  private boolean myAllCanBeIgnored;
  private boolean myAllAreIgnored;
  private FileIterationListener myListener;

  public void update(@NotNull AnActionEvent e) {
    myAllAreIgnored = true;
    myAllCanBeIgnored = true;

    // TODO: This logic was taken from BasicAction.update(). Probably it'll be more convenient to share these conditions for correctness.
    Project project = e.getProject();
    SvnVcs vcs = project != null ? SvnVcs.getInstance(project) : null;
    VirtualFile[] files = getSelectedFiles(e);
    boolean enabledAndVisible = project != null && vcs != null && !isEmpty(files) && isEnabled(vcs, files);

    e.getPresentation().setEnabledAndVisible(enabledAndVisible);
  }

  private VirtualFile @Nullable [] getSelectedFiles(@NotNull AnActionEvent e) {
    if (e.getPlace().equals(ActionPlaces.CHANGES_VIEW_POPUP)) {
      Iterable<VirtualFile> exactlySelectedFiles = e.getData(ChangesListView.EXACTLY_SELECTED_FILES_DATA_KEY);
      if (exactlySelectedFiles != null) {
        return JBIterable.from(exactlySelectedFiles).toList().toArray(VirtualFile[]::new);
      }
    }
    return e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY);
  }

  protected boolean isEnabled(@NotNull SvnVcs vcs, VirtualFile @NotNull [] files) {
    return ProjectLevelVcsManager.getInstance(vcs.getProject()).checkAllFilesAreUnder(vcs, files) &&
           ContainerUtil.and(files, file -> isEnabled(vcs, file));
  }

  public void setFileIterationListener(FileIterationListener listener) {
    myListener = listener;
  }

  private boolean isEnabledImpl(@NotNull SvnVcs vcs, @NotNull VirtualFile file) {
    if (SvnStatusUtil.isIgnoredInAnySense(vcs.getProject(), file)) {
      myAllCanBeIgnored = false;
      return myAllAreIgnored;
    }
    else if (ChangeListManager.getInstance(vcs.getProject()).isUnversioned(file)) {
      VirtualFile parent = file.getParent();
      if (parent != null && SvnStatusUtil.isUnderControl(vcs, parent)) {
        myAllAreIgnored = false;
        return myAllCanBeIgnored;
      }
    }
    myAllCanBeIgnored = false;
    myAllAreIgnored = false;
    return false;
  }

  protected boolean isEnabled(@NotNull SvnVcs vcs, @NotNull VirtualFile file) {
    boolean result = isEnabledImpl(vcs, file);
    if (result) {
      myListener.onFileEnabled(file);
    }
    return result;
  }

  public boolean allCanBeIgnored() {
    return myAllCanBeIgnored;
  }

  public boolean allAreIgnored() {
    return myAllAreIgnored;
  }
}


text:
Q: bootstrap columns remain stacked It's probably something simple, but I can't figure out why these columns are not aligning next to each other. Instead they are remaining stacked.
http://ashleykirk.ca/stylesheet/
Any tips?

A: You're not using the latest version of bootstrap (you're on 2.3.2). Loading in an external file of 3.3.5 makes it work fine.
Get the latest version of bootstrap from http://getbootstrap.com/

A: You're using HTML doctype unsupported by Bootstrap.
Use HTML5 doctype
<!DOCTYPE html>

redpajama_set_name: RedPajamaStackExchange