/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#pragma once

#include "StyleResolver.h"
#include "StyleScopeRuleSets.h"
#include <wtf/Forward.h>

namespace WebCore {

class StyleRulePage;

namespace Style {

class PageRuleCollector {
public:
    PageRuleCollector(Resolver::State& state, ScopeRuleSets& ruleSets)
        : m_state(state)
        , m_ruleSets(ruleSets) { }

    void matchAllPageRules(int pageIndex);
    const MatchResult& matchResult() const { return m_result; }

private:
    bool isLeftPage(int pageIndex) const;
    bool isRightPage(int pageIndex) const { return !isLeftPage(pageIndex); }
    bool isFirstPage(int pageIndex) const;
    String pageName(int pageIndex) const;

    void matchPageRules(RuleSet* rules, bool isLeftPage, bool isFirstPage, const String& pageName);
    void matchPageRulesForList(Vector<StyleRulePage*>& matchedRules, const Vector<StyleRulePage*>& rules, bool isLeftPage, bool isFirstPage, const String& pageName);

    const Resolver::State& m_state;
    ScopeRuleSets& m_ruleSets;

    MatchResult m_result;
};

} // namespace Style
} // namespace WebCore


Yesterday, Boston Police say, officers subdued and arrested a murder suspect who fired at a pursuing officer, without returning fire.

Since. Dec. 31, officers have made several other arrests of people they say either pointed guns at them or appeared to without any of the suspects being shot:

On Feb. 8, officers arrested a Mattapan Square shooting suspect who allegedly started firing again as they chased him.

On Feb. 7, officers arrested a teen they say pointed a gun at them while they tried to arrest a pal of his in Charlestown.

On Jan. 22, officers arrested a man who allegedly aimed a gun at them during a foot chase along Washington Street in Dorchester.

On Dec. 31, police subdued an alleged drug-store thief and carjacker who motioned as if he had a gun in the Back Bay.


The idea of investing in real estate used to involve forking out huge sums of money to buy property, in a person’s locality, with the hopes that it earns a profit over running costs. However, crowdfunding, and even more recently, Blockchain technology, is disrupting this model.

Buy a fraction of a house

There is a lot of promise that comes with investing in property. Rent, as well as the appreciation of property, are consistent and reliable streams of revenue and return, however, breaking into the property market is not a game for all.

Recent ideas, such as crowdfunding have simplified many aspects of traditional investments and business, but they still have their problems. Crowdfunding involves the coming together of multiple parties, in an agreement of trust, to effect an outcome that usually has to be regulated by a third-party.

In the case of real estate crowdfunding, middlemen have to be employed to sustain an agreement between multiple parties so that the proper dividends are received and the benefits are equally and fairly distributed. Cross border investments also come with their own issues.

Breaking down the walls, with Ether

REAL’s belief is that their use of Blockchain, Ethereum smart contracts, and digital currencies, or their own tokens, can alleviate these problems. REAL tokens will be used to invest in properties on their crowdfunding platform.

While some of the traditional real estate investment issues are being solved through crowdfunding, a new world of cross border and trustless investment, can be opened with Blockchain technology.

Through REAL’s platform, tangible real estate can be invested in fractionally and with digital currencies. By using the Ethereum network, smart contracts do the work.

In an Ethereum environment, the need for regulatory bodies and middlemen would seem to fall away, and with them the fees and problems surrounding potential global investment. By investing on an Ethereum Blockchain REAL propose that rental dividends, agreements between investors, and other intricate aspects of property investment – on a crowdfunded level – will be executed fairly and transparently.

Full of liquid

Disrupting traditional markets also comes with ease of accessibility and REAL claim that because of the self-contained Blockchain system, and the lack of external parties governing the flow of assets and control of parties in the crowdfunded investment, there will be high liquidity in an usually illiquid game.

As with any cryptocurrency token the growth or decline of the value of REAL’s token can be profited off, as well as the dividends returned from the true investment. Their platform aims to allow digital, crowdfunding investors the chance to turn their tokens into Ethereum, or other digital currencies, with ease.


This is a discussion on admin rights needed to start soundcard application! - Microsoft Windows ; I installed an emu soundcard (logged in as admin) in a w2k
non-networked PC. The user application s/ware to this card works fine
except only members of the admin group can run it! Login as a common
or garden user ...

admin rights needed to start soundcard application!

I installed an emu soundcard (logged in as admin) in a w2k
non-networked PC. The user application s/ware to this card works fine
except only members of the admin group can run it! Login as a common
or garden user and the app moans about not being installed properly
(which it is). Move that user to admin group, and it works. Looks
like a permissions problem somewhere - any ideas how to fix (other
than move every one to admin grp :-) )

Re: admin rights needed to start soundcard application!

mike writes:
> I installed an emu soundcard (logged in as admin) in a w2k
> non-networked PC. The user application s/ware to this card works fine
> except only members of the admin group can run it! Login as a common
> or garden user and the app moans about not being installed properly
> (which it is). Move that user to admin group, and it works. Looks
> like a permissions problem somewhere - any ideas how to fix (other
> than move every one to admin grp :-) )

I fully expect this to quickly devolve into a "why windows tends to
suck" sort of thread. :-)

But if you think about it though, it's possible you're dealing with an
application that may be doing low level direct access to the hardware
(sound card in this case), and these are the sorts of things only
privileged users get to do in the security model of most OS's.

What's the application in question anyway? Surely there are other
sound applications that interact through the driver layer that don't
require admin rights to run?

Re: admin rights needed to start soundcard application!

On 21 Dec 2006 02:26:41 -0600, comphelp@toddh.net (Todd H.) wrote:
>mike writes:
>
>> I installed an emu soundcard (logged in as admin) in a w2k
>> non-networked PC. The user application s/ware to this card works fine
>> except only members of the admin group can run it! Login as a common
>> or garden user and the app moans about not being installed properly
>> (which it is). Move that user to admin group, and it works. Looks
>> like a permissions problem somewhere - any ideas how to fix (other
>> than move every one to admin grp :-) )
>
>I fully expect this to quickly devolve into a "why windows tends to
>suck" sort of thread. :-)

Maybe - I was hoping for something more usful though.
>But if you think about it though, it's possible you're dealing with an
>application that may be doing low level direct access to the hardware
>(sound card in this case), and these are the sorts of things only
>privileged users get to do in the security model of most OS's.

Yes of course but that's not the problem here. Yes, the low level
stuff is the driver's responsibility - and not even priv users
"should" be able to just jump around that. But the user intereface to
the s. card is a user level application (just like any other). And it
is the user level appliction I am on about (just emu's patchmix
interface to it's own soundcard. It is *not* the driver.

It kind of like saying only admins can play sound on a PC! Which I'm
sure is not what you are saying.

>
>What's the application in question anyway? Surely there are other
>sound applications that interact through the driver layer that don't
>require admin rights to run?

Re: admin rights needed to start soundcard application!

mike writes:
> On 21 Dec 2006 02:26:41 -0600, comphelp@toddh.net (Todd H.) wrote:
>
> >mike writes:
> >
> >> I installed an emu soundcard (logged in as admin) in a w2k
> >> non-networked PC. The user application s/ware to this card works fine
> >> except only members of the admin group can run it! Login as a common
> >> or garden user and the app moans about not being installed properly
> >> (which it is). Move that user to admin group, and it works. Looks
> >> like a permissions problem somewhere - any ideas how to fix (other
> >> than move every one to admin grp :-) )
> >
> >I fully expect this to quickly devolve into a "why windows tends to
> >suck" sort of thread. :-)
>
> Maybe - I was hoping for something more usful though.
>
> >But if you think about it though, it's possible you're dealing with an
> >application that may be doing low level direct access to the hardware
> >(sound card in this case), and these are the sorts of things only
> >privileged users get to do in the security model of most OS's.
>
> Yes of course but that's not the problem here. Yes, the low level
> stuff is the driver's responsibility - and not even priv users
> "should" be able to just jump around that. But the user intereface to
> the s. card is a user level application (just like any other). And it
> is the user level appliction I am on about (just emu's patchmix
> interface to it's own soundcard. It is *not* the driver.

Looking at this explanation of what patchmix is, and given that it's
accessing hardware accelleration on the card, I suspect you may be
screwed.

The right folks to bitch at about it I suspect would be emu. You
might see if they have a forum or FAQ that may address whether running
this under a limited user is possible before spending too much
cranial-to-desktop time on it. It could be that their application
writers took the path of lesser resistance in allowing that app to
talk directly to the hardware vs abstracting the interface in a way
that would play well with windows hardware abstraction layer.
> It kind of like saying only admins can play sound on a PC! Which I'm
> sure is not what you are saying.

Nah, I'm saying that I bet there are sound related utilities such as
audacity or whatever that might work just fine with limited user
accounts, but if (as I suspected) this program you were trying to use
is more intimately tied to the hardware on that card, I'm guessing
that it may need more direct access to that card's hardware than an xp
limited account is willing to give. The case is strengthening for my
theory given what the software does, but only EMU's support folks are
likely to give you an authoritative word on that.


Developer

DarkGlow Games are dedicated towards making custom and varying experiences for anyone who enjoys gaming. DarkGlow Games first game is Runner a scifi futurisitc endless runner set in a futuristic modern captial city.


[Atypical presentation of angiomiolypoma in a patient with peritoneal metastases from ovarian cancer: a case report].
A renal mass with not typical instrumental characteristic in patient in follow-up for ovarian neoplasia sets to the surgeon serious doubts about proper surgical strategy. Achieve of the conservative renal surgery assisted by the intraoperative use of the radiofrequency energy has allowed to preserve the renal function and the diagnosis of unknown angiomyolipoma.


Click on the photo to view the post with instructions on how to make your own community poop bag share station.

Just a few days after I revamped my neighborhood poop bag dispenser, it was completely full of shared bags.

Typist: BethanyIn July, I revamped the homemade poop bag dispenser I had put up on our Seattle street last year. I also put two new community poop bag share stations nearby, one at the park and one on a neighbors fence post (per the neighbors request.) Just like the do-it-yourself poop bag holder I put up last fall, the two new dispensers took a little while to catch on. I am pleased to share that bothre-purposed materials poop bag holders have been pleasantly filled for a while now and Jason and I have definitely noticed less poop on the ground nearby.

These overwhelmingly positive results have not been without risk. The original utility pole poop bag dispenser that I put up is technically against City of Seattle code. I kept a close eye on it to make sure that it hasn't been an eye sore, made or turned into litter, which I believe is the main intent of this law. Also, for the safety of utility workers, I cleared old staples and nails from the pole when I put the poop bags dispenser up and when I re-did the station. Obviously, if it was removed or I was asked to take it down, I would. I couldn't find any city park regulations about putting the poop bag share station up in the park, I was fully expecting city park workers to remove it. However, that station was also one I was most hoping would catch on. The third homemade dispenser that is on private property was the least risky I installed but I feared it would not be used. In a passing conversation with the neighbor, I found out a poop bag holder attached to her fence post might help in keeping the public space behind her property cleaner. It's worked!

Completely filled fence post poop bag holder. There is noticeably less poop in the surrounding area since this station was installed.

Community poop bag share station at a city if Seattle park...

..generously filled with many rolls of bags to help all responsible dog owners scoop that poop.

Bring poop bag share stations to your neighborhood. Have you tried adding a community poop bag share station in your neighborhood?A lot of readers have expressed concerns that their cities or neighborhoods might not allow such scoop that poop reminders. Here are some suggestions to help clean up your neighborhood, provide poop nags for those who might occasionally forget or run out (it happens to the best of us!) and spread the Scoop That Poop word:

Know the law. Check your neighborhood rules and laws about posting signs and items. If you are not allowed to install neighborhood poop bag share stations on public property, add them on private property. If you put a successful station in your yard, other neighbors might want them in their yards too.

Change the rules. Attend neighborhood, park or city meetings. If city, park or neighborhood officials know the importance of adding community poop bag share stations to your streets or parks, they can create an allowance. Perhaps you can get them to allow one as an experiment (like I did with my first one.) It could prove a poop bag share station can help and not look ugly. Personally, I think anything looks better than poop on the ground!

Seek allies. If you work with other neighbors either to change the rules to allow poop bag dispensers to be installed or to put community poop bag share stations up, more people will learn how important it is to clean up after their dogs. Talk to other dog owners on your street, ask neighbors whose yards often have a lot of poop, or pass out flyers to find other neighbors that agree your neighborhood would benefit from a poop bag exchange. The neighbor whose fence post I put a poop bag dispenser on does not have dogs but has been pleasantly surprised by the results of the poop bag holder. I soon hope to find more neighbors willing to host community poop bag share stations.

The laminated waterproof paper signs do not last long but the taped over paper on the re-purposed water bottle have lasted through all seasons.

With the weather in Cascadia rapidly turning more wet and cold, it is the season of more and more dog poop getting left behind. That also means more disease gets washed into our fragile water ways. I hope to soon install a few more homemade poop bag dispensers around my neighborhood. Even the best of responsible dog owners forget or run our of poop bags every once in a while. It is possible for neighborhoods and parks to allow dog owners to help each other do what is best for the community and the environment and always, always scoop that poop.

Thank you to the Scoop That Poop hosts Sugar the Golden Retriever & My Pawsitively Pets. Please join us in raising awareness about the importance of picking up after your dog by joining the hop, clicking around the links below and/or sharing the #ScoopThatPoop wherever you can.

Nice to see that they are lasting well and working! I don't technically live in a neighborhood, although there are suburban neighborhoods surrounding our property. Most of the time, I see people carrying proper poop scooping supplies when they are walking and I don't recall seeing any stray piles lately. I guess they must have things under control over there thankfully!

Reply

Bethany

10/20/2014 10:00:47 am

Oh Good! Jason's parents live in a suburban development with strict rules about putting things like these stations up. Almost all the neighbors attend the community meetings though so everyone gets constantly reminded that scooping that poop is a paramount neighborhood rule. Maybe the suburban development around you is doing the same good spreading of the poop clean up word!

These poop bag stations are so clever! Great thinking, Bethany! I'm glad to hear they've been being used too, that's great! I've run out of bags before, it's embarrassing. I keep a roll of bags in every purse now and now that it's going to start getting colder I will be stuffing my coat pockets with them again, lol!

Reply

Bethany

10/21/2014 04:37:32 am

Thanks for the reminder to restock all my spare bags hide outs! After walking four dogs, my supplies were depleted. If I have ever run out of bags, I always go back for the poop pile. I just worry so much that someone will step in it before I get there but it makes for more speedy walking for the dogs and I!

DisclaimerCascadian Nomads are not
veterinarians, behaviorists or animal trainers. Always consult with a
veterinarian before starting or changing your pets exercise routine,
before traveling with your pet, before changing your pets diet or before
using any new pet products. Since all pets are unique individuals, consulting with a veterinarian, behaviorist or animal trainer about your pets specific needs is always recommended.

DisclosureEvery post Cascadian Nomads publishes that is sponsored by a company or brand or obtained through an affiliation with a media network will contain a disclosure paragraph. We do not use any affiliate links, just regular links to a product or company website. Cascadian Nomads only shares honest information that we feel is relevant to our readers whether a post is sponsored or not.

Privacy PolicyCascadian Nomads does not share personal information with third-parties nor do we store information we collect about your visit to this blog for use other than to analyze content performance for marketing purposes. We do use cookies and add-ons, which you can turn off at anytime by modifying your Internet browser's settings or opt out of add-ons. We are not responsible for the republishing of the content found on this blog on other Web sites or media without our permission. This privacy policy is subject to change without notice.

Copyrighted ContentPosts, words, photos or images from or featured on this blog may not be copied, reused or reproduced in any form without the prior express permission from the blog owner.


Q:

JQUERY buttonset radio multiple on one page

Hey all I'm trying to get multiple radio buttons to work on one page. This is the idea I have.
I have several selections
        Days 1 2 3 4 5
Item         x
Item 2         x
Item 3               x

I would like to recite this idea with jquery. I have the basic layout in html and i have the appriate radio buttons in place ready for selection, workds a charm, but adding the jquery buttonset doesn't work for me as a class, as an ID obviously it will change each item.
THE JAVASCRIPT
$( ".radio-days" ).buttonset();

THE PEE HAYCH PEE
<?php
    for($j = 0; $j < 5; $j++)
    {
?>

    <form>
        <div id='item<?php echo $j; ?>' class='radio-days'>
        <?php
            for($i = 0; $i < 8; $i++)
            {
            ?>
            <input type="radio" id="radio<?php echo $i; ?>" name="radio<?php echo $i; ?>" /><label for="radio<?php echo $i; ?>"><?php echo $i; ?>
            <?php
            }
        ?>

    </form>

<?php
    }
?>

in absolute dire need of help here :(

A:

You cannot assign an id with multiple elements in html. Try
<?php
    for($j = 0; $j < 5; $j++)
    {
?>

    <form>
        <div id='item<?php echo $j; ?>' class='radio-days'>
        <?php
            for($i = 0; $i < 8; $i++)
            {
            ?>
            <input type="radio" id="radio<?php echo $j; ?>_<?php echo $i; ?>" name="radio<?php echo $j; ?>" /><label for="radio<?php echo $j; ?>_<?php echo $i; ?>"><?php echo $i; ?>
            <?php
            }
        ?>

    </form>

<?php
    }
?>


When I wrote last week about a California man whose wife cut his penis off, we got an avalanche of response from the interwebz, especially thanks to linkage from some men’s interest blogs and a few MRA dudes. I was called a “hypocrite,” “scum”, and a “dick-hating bitch” (the more hateful and rape apologist comments didn’t make it out of moderation, but we kept some of the milder ones in). Some claimed that I didn’t condemn the attack, which is untrue. I did, strongly, in the concluding paragraph (a hint: next time try reading the whole post until you get to the “very, very wrong” part). The other criticisms were that I was somehow being hypocritical or exercising a “double standard” when it comes to violence against men vs. violence against women and that I semi-jokingly said I kept a list of men who I might like to see meet the same fate. I’ll unpack those last two, for the record.

I don’t know if the woman in this case was a victim of domestic violence. I pointed out that she told police her husband “deserved it” and that our society is pretty fucked up if we start wondering about domestic violence and whether the man had it coming immediately upon hearing about such a crime. On that, I think we can all agree. At no point did I say he deserved what happened to him.

But I am not being hypocritical when I said that I understand the urge for female victims to react violently against men who hurt them. Fighting back against your attacker—yes, even violently—is not in any way hypocritical. It’s a completely rational response for any person, particularly when you cannot get justice or protection by other means. Violence may not be the ideal response, but to act as though the ideal response is for women to “rise above” and passively accept victimization—especially when law enforcement fails them—shows either a superhuman tolerance for violence and injustice, or outright support for the attackers.

Now, when I said that I have a “list” of men who I think should be parted from their penises, I was being somewhat flippant, and I understand that flippancy rubbed some people the wrong way, particularly given that we don’t really know much about this particular case, and it doesn’t seem like the man in question has a history of raping and abusing his wife (unlike, say, John Wayne Bobbitt).

However, I am not going to apologize for entertaining some “Dexter”-like revenge fantasies about vigilante justice. We live in a world where one in four women is the victim of sexual assault and domestic violence is the leading cause of injury to women ages 15 to 44. Restraining orders sometimes protect women—but often don’t. Female victims are routinely dismissed by law enforcement or slandered by the media, while abusers and rapists are acquitted every single day. Men like Dominique Strauss-Kahn, Roman Polanski, elected officials, and police officers frequently use their money and influence to escape justice for their crimes against women. When these predators don’t go to jail, it’s naive and illogical to think they won’t attack women again—and continue to get away with it. They will, and as a result, women will continue to lose faith in the justice system and be less likely to report assaults.

So is it any wonder that women like me entertain revenge fantasies after being bombarded with proof that society will not protect us or condemn our attackers? When justice is denied, hell, when we’re told we don’t deserve justice because we were foolish or drunk or dressed slutty or dating an asshole or just should have known better…of course we are enraged and, yes, we might even think violence sounds like a good response. Hence, my mental list of dudes who have it coming. Frankly, if they’re not imprisoned, the only way to be sure some men won’t continue to harm women is if they are dead or dickless. I like to imagine that happening, even if I wouldn’t actually take up a gun or a knife myself.

To the men who found what I wrote so objectionable, I invite you to change places with me and try living with the constant threat of rape and violence and the knowledge that you’ll likely be blamed or ignored if it happens to you. See if you wouldn’t occasionally fantasize about fighting back by any means necessary. In return, I promise that when you do, I won’t call you a hypocrite.

11 Responses to “On Revenge Fantasies and Accusations of Hypocrisy”

I’m not going to call you a hypocrite, but I am going to express my sense that entertaining and publishing violent revenge fantasies is not a useful or healthy response to this particular incident. I feel it contributes nothing to the larger culture except more violence, and it will invite more and more violence (e.g. the hateful comments that were directed at you).

I am not a rape survivor myself. I am a woman, and aware that this makes me vulnerable to rape in specific ways. I have entertained violent fantasies against rapists as a way of dealing with a friend’s rape, or when rapists get away with their crimes. I may have confessed these fantasies to one close friend, but I would not put them out there in a public forum where they will engender more violent responses and possibly alienate allies against the rape culture.

I would not expect the public to tell me it’s okay to have these thoughts — I don’t believe it is. I believe that revenge fantasies can be natural or inevitable, but I don’t believe they should be indulged. Instead, I treat them as a (private, internal) stepping stone toward talking about the rape culture in a productive and non-violent way, and supporting the victims of assault (sexual and otherwise).

I’m definitely not comfortable with the content of these posts — the publishing of violent fantasies in a way that seemed to ask for approval, and then a published-violent-fantasy-apologia. You have every right to feel what you’re feeling, and you certainly have the right to post on your own blog, but I’m afraid I can’t entirely support the way this has played out.

Kari, that’s totally fair and I respect your opinion—we clearly have different reactions to the same feelings, and different comfort levels with expressing them in public.

That said, I really don’t think that my being honest about having revenge fantasies will invite more and more violence (e.g. the hateful comments that were directed at you). Or alienate allies or somehow provoke more violence against women.

Rapists and misogynists will hate/attack women whether we’re silent or we’re vocal—so why be silent? Doesn’t that just play into their hands? And if they want to make hateful comments, let them. It only shows them for who they really are.

There’s a really good point you brought up here: I am not being hypocritical when I said that I understand the urge for female victims to react violently against men who hurt them. Fighting back against your attacker—yes, even violently—is not in any way hypocritical. It’s a completely rational response for any person, particularly when you cannot get justice or protection by other means. This is the key piece that gets lost in many dv cases. Similarly people say, why did she stay? This is the answer to why, partly.

Here’s the link for a somewhat famous movie http://telling.psu.edu/ about dv. A detective involved in this case, Deirdri Fishel:

And you’ll never hear me in any of my cases that I prosecute, talk about a victim who won’t testify. Because if we could guarantee a victim that they would be safe, that the outcome of the court case would be better for them, then I believe that a victim would testify. But we can’t guarantee that.

This is why Becky is exactly correct to say she’s not being hypocritical in her blog posts. Because the system will not back up women.

The attitude “If Bobbit didn’t want his dick cut off, maybe he should’ve refrained from raping his wife” might not be ethically perfect, but it’s certainly the one I take too.

The problem with I invite you to change places with me and try living with the constant threat of rape and violence and the knowledge that you’ll likely be blamed or ignored if it happens to you., though, is that in the case of California man, it’s exceedingly likely that he was living under the constant threat of violence, and he’s being used as the butt of a joke for it in the media, and being blamed for it here (at least, the implication is there).

A lot of it too, is underselling how much men understand these things. I won’t speak for anyone else who complained, but I have had abusive partners, and I was terrified of them. Not that I was afraid I was going to die, but I’m pain-averse enough that I was terrified nonetheless. And I perfectly well I’d be blamed, or ignored, or ridiculed, if I said anything about it. And so the “men just can’t understand thing” does rile my emotions up.

Thanks for that, Brian. Your experience is something I hadn’t considered, and should have. The way society treats male victims of d.v. is another example of how the Patriarchy hurts men too—male victims are mocked as not sufficiently manly enough. Which is both victim-blaming AND subscribes to the sexist notion that men are meant to dominate women and are somehow a failure as a man when they don’t.

I would never claim that men can’t be victimized or are not victimized, although I will point out that even if you take underreporting into account, the stats show that female victims significantly outnumber male ones, particularly in homicide cases.

I also know from experience, there are many, many men who understand rape culture and empathize perfectly well what women are up against (most of them are, to my knowledge, not victims of d.v.). Some of those men responded in the original thread, but most of them were Harpyness regulars. It’s only when the links went up to MRA sites that the haters and apologists started showing up, and it’s them who I was addressing. I’m sorry if it read like a diatribe against men in general, including yourself; that’s not how it was intended.

I don’t know where these MRA guys get off, because if you ever read the comments section of one of those blogs and how they talk about female victims of violence and all sorts of revenge fantasies they share about their ex-wives, it seems to me that THEY’RE the ones being hypocrites, really.

I am also a victim of rape and routinely think about what I could do to scar my attacker for life. The law failed me in so many ways that sometimes the only way I can come down from being triggered or having a day when I think about it too much is to think nasty thoughts. Good to know that I should never, EVER post about that experience because it would offend some people’s sensibilities.

Also not helping victims? Telling them what actions, feelings, and thoughts are ‘appropriate’.

Wait a minute. Any kid can go into a store and buy a video game in which women are maimed and killed and people were calling you out for having revenge *fantasies*?

Kari, I don’t agree that revenge fantasies are unhealthy. I think that, like other kinds of fantasies, they can be a helpful way of processing feelings that can’t be satisfactorily addressed in real life. Bad things happen to good people sometimes, and justice isn’t always served. As long as you keep control of the fantasies and don’t let them take over your life, I think they’re a reasonable reaction to a world that can be violent, scary, and unjust.

One of the reasons I love murder mysteries is that they satisfy my personal wish to balance the scales. Lisbeth Salander gets revenge better than anyone.

As long as you keep control of the fantasies and don’t let them take over your life, I think they’re a reasonable reaction to a world that can be violent, scary, and unjust.

I hopped on to say something to this effect, and then mischiefmanager beat me to it. I tried (somewhat bumblingly) to say something about this over at one of the blogs that linked to the earlier post and I don’t think I was very articulate. I’m someone who believes firmly in nonviolent practice, and tries to cultivate lovingkindness towards others in my thoughts and feelings. I also think that the responses we have (even the ones we find unsavory or embarrassing or frightening) can be super instructive vis a vis understanding how we are affected by culture.

So I don’t think it’s “hypocritical” to have an emotional response to a story like the OP story that wonders whether there was long-term domestic violence involved (him against her or her against him). What WOULD be wrong is to have that response and not recognize the difference between that and the actual evidential truth of a specific case. What WOULD be wrong is to actually blame the victim, rather than acknowledge that our culture conditions us to suspect male-on-female domestic violence as a background for these stories. What WOULD be wrong is to call for actual bloodshed against all men and/or all abusers … or to use violent rhetoric toward men as a class. I don’t think it is wrong to acknowledge that human beings are complicated and we often have emotions that are contradictory and impulsive. We are at our best when we do not act on impulse, but separate fantasy from actual fact. Which is more or less what several folks have said here already.

My partner is the survivor of an abusive relationship, and when she is having a bad dissociative episode (or sometimes when she just mentions something off-hand that tells me how poisonous the relationship was) I have the immediate urge to do real physical harm to her ex-partner. I have occasionally voiced that urge because I think it’s important for my partner to know how categorically wrong I think the abuse was, and how strong my emotional reaction is. That does not mean I would ever actually act on the impulse to do physical harm towards someone who was not immediately threatening my physical safety.

Sometimes, I think the strange quasi-private, quasi-public realm of internet blogging blurs folks’ sense of what sort of conversation is happening in what sort of space. This is a public blog, yes, but it’s also a fairly personal blog … a collection of personal voices. Becky’s original post was not an official op-ed somewhere or a policy piece nor a call for actual specific actions. I think that it’s okay in the space of a blog like this to acknowledge our knee-jerk reactions and think about how those reactions reflect on the culture in which we live and on ourselves.

I really hate it when, in response to an act of violence, cruelty and/or oppression, a person who is not necessarily even the victim of said act(s) expresses the desire to get stabby or burny with the perpetrator of said act(s), and a third party claims such revenge fantasies make that person just as bad as the act(s) that inspired them.

Also, spend some time perusing http://manboobz.com/ if you want a wake-up call about which sex glorifies/obsesses about violence against the other.

The revenge fantasies didnt bother me, I chop up some driver cutting me off in my mind each commute. Whats interesting though is the original post seems to do what we all want to stop doing, it seems to blame the victim for causing his own tragic circumstances, or its what came to mind first. Like thats some universal human trait we need to work on overcoming.

Except for retaliation, collateral damage, wrongful application due to mistaken identity, undermining the administrative efficiency of the state, and just generally freaking people out, vengeful violence can be pretty awesome.


Saidy Brown was 14 when she discovered that she was HIV positive. Now 22, she tells CYNTHIA MASEKO about the day that changed her life.

"It was June 16, Youth Day. An NGO came to my school to educate us about HIV. Someone asked me if I wanted to take a HIV test. Being young and innocent, I agreed. My result came back positive. I could not understand it because I had never had sex.

"That's when I found out what killed my parents: they both died from HIV-related diseases. Because they both passed when I was so young, I didn't know what killed them. I was born HIV positive.

"I was living with my aunt but I was too afraid to tell her that I was HIV positive because I was scared that she would judge me. I was confused and emotional. It was too much for a 14-year-old girl. I recall asking myself if my life was a curse or a punishment. I eventually told my maths teacher and we both told my aunt. She confirmed that my parents had died from AIDS.

"Although it is painful knowing that I am the only one in the family living with HIV, my mind is at ease just knowing that my siblings are HIV negative. And I am glad that I am still alive because some babies who were born with the virus don't survive. That just goes to show that I was born on this earth for a greater purpose than being HIV positive. Two lines on an HIV test will not bring me down.

"With positive living and my ART, I can still live a long and awesome life. My advice to young people who are living with HIV is that they need to understand that it is not the end of the world."

AllAfrica publishes around 800 reports a day from more than 140 news organizations and over 500 other institutions and individuals, representing a diversity of positions on every topic. We publish news and views ranging from vigorous opponents of governments to government publications and spokespersons. Publishers named above each report are responsible for their own content, which AllAfrica does not have the legal right to edit or correct.

AllAfrica is a voice of, by and about Africa - aggregating, producing and distributing 800 news and information items daily from over 140 African news organizations and our own reporters to an African and global public. We operate from Cape Town, Dakar, Abuja, Monrovia, Nairobi and Washington DC.


The Courage that Came Before

by GPPA Co-chair Sheri Miller

I read a comment in Facebook recently that was a lament about all the protesting that’s been going on. The woman who wrote it felt that these public displays in the streets were disturbing and not the best way to change things. You can imagine the firestorm of comments that followed. I was actually glad this was posted, because the discussion that was generated prompted me to revisit my history as a woman and I developed a renewed gratitude for the courage and sacrifices of those historical women who brought about the freedoms I have today.

The women’s suffragists in the early 20th Century were the first to use the protest march (parade) down the streets of Washington as an effective tool of change. It wasn’t the only tool – civil disobedience in the form of sit-ins, strikes, and defiance of unjust laws were all used to gain public support and pressure those with power to give up some of their control and do the right thing.

Change never comes easily or quickly. It took 100 years after the first meetings for women to achieve the right to vote in 1920. It took another 100 years to overturn some of the worst of the restrictive rules and laws that were used to maintain control over us: like women could not own land, or serve on juries, or keep their own names, or even wear something other than dresses to work or school. Some of these wins were fairly recent. (I can still remember not being allowed to wear pants to public school.) These freedoms (which should have been self-evident) were not just given to us; they were fought for, over the past 200 years.

Women today need to connect to their pasts for understanding and inspiration to find that same courage. Our freedom is precious. We need to be willing to fight to hold on to what has been gained, even if it means carrying a sign in the street. And, although we have won much, we have a long way to go. We need to fight for the future; against inequality, the acceptance and normality of violence against women, and the lack of representation in all aspects of life that affect us – government offices, board rooms, courtrooms. We need to move forward toward a world where women are truly free to make their own decisions for their own lives.

GPPA News Highlights

edited by Jim Beggs and Sheri Miller.

Register Now! GPPA Convention, 3/24 - 3/25

by Tim Runkle

Join us in Pittsburgh for the March 23-24 Convention and business meeting of the GPPA state committee. Greens and supporters across the state come together for this weekend event to be held at the Pittsburgh Mennonite Church in Swissvale, 2018 S Braddock Ave, Pittsburgh, PA You can reserve your seat by registering at https://www.gpofpa.org/2019_03_conv. We plan to strengthen our activism and electoral campaigns by focusing on bringing a Green New Deal to Pittsburgh and Pennsylvania.

We are excited to include the voices of local community leaders in our workshops touching on the issues of fracking, nuclear energy, demilitarization and oversight of police, good governance, and anti-corruption. To kickoff the event, we will be joined by three voices of the Green Party of the U.S. who will discuss the vision and needs of the Green Party as we approach the 2020 election, Presidential candidates Dario Hunter and Ian Schlakman and three-time NY gubernatorial candidate Howie Hawkins.

Saturday requires registration and a $40 fee for participation. For those that may not be able to provide a full fee please send us an email at contact@gpofpa.org for sponsorship by one of our Members. Sunday will include the business meeting for GPPA delegates, and it will be open to the public at no charge. Activities will be held between 10 am and 5 pm, with additional events in the evening.

Green Party of Allegheny County Fundraiser

The Green Party of Allegheny County is having a fundraiser to help support local activities, including their goal to field at least five electoral candidates.

Members of the Allegheny County local are active on many different issues including PNC’s divestment from war, curbing economic dependence on petrochemicals, and developing a platform for a Green New Deal that puts people above profits.

Funds donated will be matched 1:1 by another donor and benefit the Green Party of Allegheny County.

Additional details are available here.

PA Greens call H.R. 1, "Onerous and Deceptive"

"The Green Party of Pennsylvania opposes any provisions in U.S. House Resolution 1 (H.R.1) that would work to vilify or weaken progressive voices, and we are against the proposed changes for the federal matching funds program."

"H.R.1 is a deceptive bill. A quietly tucked-away provision of H.R.1 will make it nearly impossible for anyone outside of the two-party system to run for president. Making it easier for people to vote will NOT improve democracy if the only choices on the ballot are the rich or the chosen!".

Read the full press release.

Wolf's Plan Won't Restore Pennsylvania by Tim Runkle

In February, the Green Party of Pennsylvania released an in-depth policy statement of why Tom Wolf's Restore Pennsylvania plan won't achieve the goal of restoring the Commonwealth's environment. Key points include:

1) Underfunding and understaffing of the Department of Environmental Protection during the Wolf administration.

2) The state becomes dependent upon a severance tax on shale gas extraction for revenue.

3) An increased approval rate for gas wells and pipelines is not the path for Pennsylvania's sustainable future.

Read the full statement here.

Green Party Gadfly

Beginning in 2008, Mort Malkin, a member of GPPA has been writing "Gadfly," a political satire blog. "Gadfly" pokes fun at those in public life who deserve it. It is free for the reading and the passing on to others. As Mort says, "Laughter is the best political medicine for society."

Team Updates

Communications Report by Chris Robinson

Communications TeamWe hope that you approve of the March GREEN STAR. The Communication Team is still looking for a few good people who want to learn:

How to post content to www.gpofpa.org;

How to layout the GREEN STAR on NationBuilder;

How to post emails to our NationBuilder list;

How to host our ZOOM meetings.

If you would like to join the Communication Team, please contact me at chrisrecon-at-netzero-dot-net or at 215-843-4256, or sign up here.

Finance Report by Tim Runkle

Finance TeamFinance Team is seeking volunteers who have a drive to connect Greens across the state. The Finance Team has developed a phone-banking plan with the intent that we reach out to every Green in Pennsylvania. Our volunteers will introduce Greens to our statewide organization and help them find their local chapters. We want to offer them a path to participate in the Green Party Membership Program. If you can help, please message us at contact@gpofpa.org or sign up here.

GreenWave Report by Jenny Isaacs

GreenWaveThe 2019 campaign season is now underway, and the Green Party of PA is actively seeking potential candidates for municipal offices such as township board of supervisors, borough council, or school board and county positions such as commissioner, clerk of courts, and sheriff. An overview of available offices can be found on our Green Wave Website. Please reach out to your nearest coordinator or email Green Wave with questions!

YOU CAN HELP by sharing this call for candidates with anyone you feel represents our Four Pillars and Ten Key Values. If you are considering approaching activists you know about running Green, please begin the conversation with them as soon as possible. Candidates who want to run as Greens must be registered as Greens 30 days before the primary.

Green candidates may start collecting voter signatures for general election ballot access on March 13 this year, and may file their nomination papers any time before August 1. Many municipal offices only require a dozen or so signatures, and on-the-ground conversations about issues important in your community are one of the best ways to grow the Green Party.

With Greens holding 19 elected positions in PA, we rank second in the country (behind only California)! And we have an ambitious goal of running 35 candidates this year. Please help us grow the party and the movement by stepping up to run for local office yourself, or by bringing us a candidate from your community. Our phone calls are the 2nd and 4th Wednesday of each month. It takes hundreds of Greens just like you to make the Green Party work. We are a people-powered party!

National Green News

edited by Dave Ochmanowicz

Greens vs. Greed: The Greens go to Washington!

Greens from all over the USA will join together April 1-5, 2019 in Washington to lobby their congresspeople by asking them to take the the "Public Funding Only Pledge". Additionally, they will be asked to sponsor or co-sponsor a bill in Congress to free our elections from any sort of bribery cash: special interest PAC, corporate or dark money donations. Instead, qualified candidates from every party would get an equal chance in TV, radio and printed ads, debates and appearances. This would allow other voices to be heard and the American voters to be aware of all of their choices.

New London Green Places High 2nd in Race for CT House of Representatives

A Special Election was held on Tuesday, February 26, to fill the 39th district seat, Connecticut House of Representatives, that was vacated by Chris Soto, who has joined Gov. Lamont's administration as Legislative Affairs Director.

The election results were as follows:

Anthony Nolan (Democrat): 963 votes (51.33%)

Mirna Martinez (Green): 535 votes (28.52%)

Goulart (Republican/Independent): 276 votes (14.71%)

Jason Catala (Petitioning): 102 votes (5.44%) (show all)

Forget Red vs. Blue: The Paradigm for the 21st Century is Orange, Purple, and Green

by Scott McLarty, former media director of the Green Party of the United States

"By now, most of us have noticed a paradigm shift that has made traditional political labels obsolete. Red versus Blue (Republican conservative right-wing versus Democrat liberal left-wing) seemed to work for the last century, but it's not working for the mess we're in now."

Continued Climate Chaos: The True Cost of Reliance on Fossil Fuels

Help us stop H.R. 1, the "Voting Rights" bill that restricts voter choice!

Green Party's Working Group on Reparations stands with family of child arrested for not standing for Pledge of Allegiance

Green Party members testify at NY hearing on climate crisis

Global Green News

edited by Sheri Miller

Browsing the international Green news can be very uplifting. Greens are fighting for a brighter future throughout the world and have had many successes around the globe!

Canadian Greens nominate George Orr for 2019 federal election

Mr. Orr, a well-known Canadian journalist, believes he will win. "I'm going to be the Bernie Sanders of the Canadian Green Party," he said. "I am that guy."

The Netherlands is paying people to cycle to work

shared by the Asia Pacific Young Greens Network

GPPA Coming Events

edited by Chris Robinson

(To submit a proposal for your county to organize an in-person state meeting or another local, state-sponsored event, fill out the Event Hosting Application Form.)

March

Green Party of Wyoming County annual meeting

Please contact Jay Sweeney

March

Green Party of Philadelphia meeting

For details, please contact gpop@gpop.org

March 5, 10:00 am

Neighbors Against the Gas Plants

Appeal hearing, Phila. License & Inspections, 1515 Arch Street, Philadelphia, PA

March 5, 6:00 pm

Green Party of Allegheny County meeting

Panera Bread community room, 3401 Boulevard of the Allies, Pittsburgh, PA

info@alleghenycountygreens.org

March 7, 7:00 pm

Green Party of Delaware County meeting

Swarthmore Borough Hall, 2nd Floor Community Room, 121 Park Avenue, Swarthmore, PA; contact jbowserb@yahoo.com

March 7, 2019

Chester County Green Party virtual meeting

Please contact Chair Beth Scroggin

March 11, 7:00 pm

Lackawanna County Green Party monthly meeting

2043 N Main Ave, Scranton, PA. Please contact Jen Bruno for details at Lackawanna.Greens@gmail.com

March 13

Begin to Circulate Green Party Nomination Papers

Contact your local Green Party or GPPA Green Wave

http://www.greenwaveofpa.com/contactus

March 16, noon

Hands Off Venezuela!

Lafayette Square, 1608 NW H Street, Washington, DC

https://www.facebook.com/events/242059076711261/

March 18, 7:00 pm

Bucks County Green Party Meeting

Jules Pizza, 78 South Main Street, Doylestown, PA

https://www.gpofpa.org/bucks_county

March 18

Montgomery County Green Party Meeting

Michael's Diner, 501 South Easton Road, Wyncote, Pa

https://www.montcogreens.com/

March 23 10:00 am through March 24, 5:00 pm

GPPA Convention

Convention and business meeting of the GPPA state committee

Pittsburgh Mennonite Church in Swissvale, 2018 S Braddock Ave, Pittsburgh, PA.

Details above in GPPA News. Reserve your place at https://www.gpofpa.org/2019_03_conv

March 30, noon

Protest at Drone War Command

Brandywine Peace Community, Bucks County Green Party, Montgomery County Green Party,

Green Party of Philadelphia, gpop@gpop.org

Air Guard Station, Easton Road (#611) at County Line Road, Horsham, PA

http://www.brandywinepeace.com/events/

March 30, 1:00 pm

No to NATO, War & Racism

Lafayette Square, 1608 NW H Street, Washington, DC

https://www.facebook.com/events/487410295119547/

March 30, 6:00 pm

Beef & Beer Dance Party

Fundraiser for 12th Annual May Day USA Celebration,

Endorsed by Green Party of Philadelphia, gpop@gpop.org

SEIU Union Hall, 455 North 5th Street, Spring Garden, Philadelphia.

https://www.facebook.com/events/2345445422344115/

March 31, 1:00 pm

Concert for Peace and Ending War

Franklin Square, 1300 NW I Street, Washington, DC

https://www.facebook.com/events/565415643869644/

April 1 thru 5

Green Party Lobby Days

Talk with your Representative about public funding for elections. Visit Washington, DC

https://greensvsgreed.org/about-the-lobby/

April 3, noon

No to NATO, Yes to Peace, Festival

Saint Stephen's Church, 1525 NW Newton Street, Washington, DC

https://www.facebook.com/events/597421017354062/

GPPA Meeting Dates for 2019:

March Convention: Saturday - Sunday, March 23-24

May Virtual Meeting/Spring Web Conference: Sunday, May 19th, 12pm-4pm

Summer Retreat: Saturday - Sunday, July 13-14

September Virtual Meeting/Fall Web Conference: Sunday, September 15th, 12pm-4pm

Fall Conference & Celebration: Saturday - Sunday, November 16-17 Web Conferences are online - RSVP to get connection information. The locations for in-person conferences are to be determined. In-person conferences can be hosted by counties, county groups or regions. These events are fundraisers. When hosted locally, the host group receives back half of the revenue after expenses. To apply for hosting, submit your info to our Application for Local Hosting of GPPA State Meetings or GPPA-Sponsored Events. We strive for geographic diversity in reviewing applications, however, all submissions are considered.

Green Party of Pennsylvania Communications Team & Media Committee

Issue Credits:

EDITORS: Sheri Miller, Chris Robinson, Dave Ochmanowicz Jr., & Jim Beggs

CONTRIBUTORS: Jay Ting Walker & Tim Runkle

GRAPHIC ARTS: Kevin Richardson

Everything we do is based on our Four Pillars and Ten Key Values. If you find that you share these ideals, come and join the movement.

You can support the Green Party in many ways; however, a monthly sustaining donation helps to fund a solid infrastructure to help local chapters coordinate candidates and provide resources to make their campaigns successful. As little as $3 per month can have a significant impact!

Sustaining Donation Single Donation Purchase Green Merchandise

Join us and help bring about a future where people and planet are valued over profits. We have a new, tiered membership structure that allows you to determine your level of commitment and support. And if you want to get more directly involved, consider joining an action team. Work with other committed progressives and activists in activities such as planning events, developing media content, or helping with campaigns. Let's join together to make 2018 the year of progressives!

The Green Star is an official publication of the Green Party of Pennsylvania Communications Team * 2019


Q:

Chrome on android - not loading local website javascript and css

I have strange problem on Chrome for Android with local website.
It works perfect on Firefox for Andorid, but not for Chrome.
On my site here: https://passcombo.com there is download link with a zip file.
What I do is:

download file to local file system (not SSD! - external storage makes
another problem!)
I unzip the package and go to the site in local storage using File Commander
I open the html file with Chrome - only HTML loads, no CSS, no JS, no images, no fonts.

Looks like there is path problem with relative paths?
But firefox works!
Working alternative is Firefox, but there you need to write correct strange path: "file:///storage/emulated/0/..../...html"
But...
Currently Chrome is mostly used on Andorid so it's bad local sites not working :/

A:

It doesn't work opening with file explorer, you have to write the path in the address bar file:///sdcard/Download... or wherever.
JS works with Chrome on local html file in my Galaxy S6.

A:

The only solution I found is to:

use firefox
copy folder with my html/css/js to local storage
(somewhere)
open the site in firefox with path like: file:///storage/emulated/0/myfolder/index.html

where 'file:///storage/emulated/0/' is the main path to local storage, and if you copied your folder somehwre deeper then you need to change the 'myfolder' to /somefolder1/somesubfolder/.../ sth
Shame it's the only way to create a web browser app for adroid.


Cost-effectiveness of adult pertussis vaccination in Germany.
The incidence of pertussis in adults is high despite good childhood vaccination coverage. An adult formulation of an acellular pertussis vaccine is licensed and available for use in Germany. To evaluate the potential health benefits, risks, costs and cost-effectiveness of routine pertussis vaccination programs for German adults. A Markov model was used to simulate health states and immunity levels associated with pertussis disease and vaccination. The following strategies were evaluated: (1) no adult pertussis vaccination, (2) one-time adult vaccination at 20-64 years, and (3) adult vaccination with decennial boosters. Our main outcome measures were costs (2006 Euros), cases prevented, incremental cost per case prevented and incremental cost per quality-adjusted life year (QALY) saved. We performed sensitivity analyses for key assumptions in the model including disease incidence, vaccine cost, vaccine efficacy, disease costs and frequency of adverse events. Future costs and benefits were discounted at 3%. At a disease incidence of 165 per 100,000, the one-time adult vaccination strategy would prevent 498,000 cases, and the decennial adult vaccination strategy would prevent 1 million cases. Approximately 31 million adults ( approximately 62% of the cohort) would be vaccinated with a one-time adult vaccination strategy for a total program cost of 366 million Euros, while a decennial vaccination strategy would cost 687 million Euros. The one-time adult vaccination strategy resulted in CE ratios of 5800 Euros per QALY saved, or 160 Euros per pertussis case prevented. The decennial booster strategy cost 7200 Euros per QALY saved, or 200 Euros per case prevented. The results were most sensitive to assumptions about disease incidence and vaccine cost. Routine vaccination of German adults aged 20-64 years with Tdap is cost-effective.


Rare BRIP1 missense alleles confer risk for ovarian and breast cancer.
Germline loss-of-function mutations in BRIP1 are associated with ovarian carcinoma and may also contribute to breast cancer risk, particularly among patients who develop disease at an early age. Normal BRIP1 activity is required for DNA interstrand crosslink repair, and is thus central to the maintenance of genome stability. Although pathogenic mutations have been identified in BRIP1, genetic testing more often reveals missense variants for which the impact on molecular function and subsequent roles in cancer risk are uncertain. Next generation sequencing of germline DNA in 2,160 early-onset breast cancer and 1,199 ovarian cancer patients revealed nearly 2% of patients carry a very rare missense variant (MAF<0.0001) in BRIP1. This is 3 fold higher than the frequency of all rare BRIP1 missense alleles reported in more than 60,000 individuals of the general population (p<0.0001, Chi-square). Using CRISPR-Cas9 gene editing technology and rescue assays, we functionally characterized 20 of these missense variants, focusing on the altered protein's ability to repair interstrand crosslink damage. 75% of the characterized variants rendered the protein hypomorph or null. In a clinical cohort of >117,000 breast and ovarian cancer patients who underwent panel testing, the combined odds ratio associated with BRIP1 hypomorph or null missense carriers compared to the general population was 2.30 (95%CI=1.60-3.30, p<0.0001). These findings suggest that novel missense variants within the helicase domain of BRIP1 may confer risk for both breast and ovarian cancer and highlight the importance of functional testing for additional variants.


/*
   Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
*/

#include "mysql_query_runner.h"
#include "instance_callback.h"
#include "sql_string.h"
#include "m_ctype.h"

using namespace Mysql::Tools::Base;
using Mysql::I_callable;
using Mysql::Instance_callback;
using std::vector;
using std::string;

Mysql_query_runner::Mysql_query_runner(MYSQL* connection)
  : m_is_processing(new my_boost::atomic<bool>(false)),
  m_is_original_runner(true),
  m_connection(connection)
{}

Mysql_query_runner::Mysql_query_runner(const Mysql_query_runner& source)
  : m_result_callbacks(source.m_result_callbacks),
  m_message_callbacks(source.m_message_callbacks),
  m_is_processing(source.m_is_processing),
  m_is_original_runner(false),
  m_connection(source.m_connection)
{
}

Mysql_query_runner::~Mysql_query_runner()
{
  if (m_is_original_runner)
  {
    for (std::vector<I_callable<int64, const Row&>*>::iterator
      it= m_result_callbacks.begin(); it != m_result_callbacks.end(); ++it)
    {
      delete *it;
    }
    for (std::vector<I_callable<int64, const Message_data&>*>::iterator
      it= m_message_callbacks.begin(); it != m_message_callbacks.end(); ++it)
    {
      delete *it;
    }

    delete m_is_processing;

    mysql_close(this->m_connection);
  }
}

Mysql_query_runner& Mysql_query_runner::add_result_callback(
  I_callable<int64, const Row& >* result_callback)
{
  m_result_callbacks.push_back(result_callback);
  return *this;
}

Mysql_query_runner& Mysql_query_runner::add_message_callback(
  I_callable<int64, const Message_data&>* message_callback)
{
  m_message_callbacks.push_back(message_callback);
  return *this;
}

MYSQL* Mysql_query_runner::get_low_level_connection() const
{
  return m_connection;
}

int64 Mysql_query_runner::run_query_store(
  std::string query, std::vector<const Row* >* result)
{
  Store_result_helper helper(result);
  return this->run_query(query, helper.get_result_callback());
}

int64 Mysql_query_runner::run_query(
  std::string query,
  I_callable<int64, const Row& >* result_callback)
{
  Mysql_query_runner copy(*this);
  copy.add_result_callback(result_callback);
  int64 result= copy.run_query(query);
  delete result_callback;
  copy.m_result_callbacks.clear();
  return result;
}

int64 Mysql_query_runner::run_query(string query)
{
  bool expected_value= false;

  /*
    Try to change processing flag to true. If it's not false already, this
    means that another query is in progress, which is not allowed.
   */
  if (!m_is_processing->compare_exchange_strong(expected_value, true))
  {
    Message_data message(1, "Cannot execute more than one "
                            "MySQL query in parallel on single MySQL connection.",
                            Message_type_error);
    return this->report_message(message);
  }
  uint64 result= this->run_query_unguarded(query);
  *m_is_processing= false;

  return result;
}

int64 Mysql_query_runner::run_query_unguarded(string query)
{
  if (0 != mysql_query(m_connection, query.c_str()))
    return this->report_mysql_error();

  MYSQL_RES* results= mysql_use_result(m_connection);

  if (results != NULL)
  {
    for (;;)
    {
      // Feed result callbacks with results.
      MYSQL_ROW row= mysql_fetch_row(results);

      if (row == NULL)
      {
        // NULL row indicates end of rows or error
        if (mysql_errno(m_connection) == 0)
          break;
        else
        {
          mysql_free_result(results);
          return this->report_mysql_error();
        }
      }

      unsigned int columns= mysql_field_count(m_connection);
      Row* processed_row= new Row(results, columns, row);

      vector<I_callable<int64, const Row& >*>::reverse_iterator it;
      for (it= m_result_callbacks.rbegin();
        it != m_result_callbacks.rend();
        it++)
      {
        int64 callback_result= (**it)(*processed_row);
        if (callback_result != 0)
        {
          mysql_free_result(results);
          return callback_result;
        }
      }
    }
    mysql_free_result(results);
  }
  else
  {
    if (mysql_errno(m_connection) != 0)
      return this->report_mysql_error();
  }

  // Get all notes, warnings and errors of last query.
  if (0 != mysql_query(m_connection, "SHOW WARNINGS") ||
      NULL == (results= mysql_use_result(m_connection)))
  {
    this->report_mysql_error();
    return 0;
  }

  // Process all errors and warnings.
  for (;;)
  {
    // Feed message callbacks with results.
    MYSQL_ROW row= mysql_fetch_row(results);

    if (row == NULL)
    {
      // End of rows or an error.
      if (mysql_errno(m_connection) != 0)
        this->report_mysql_error();
      break;
    }

    unsigned int columns = mysql_field_count(m_connection);
    Row* processed_row= new Row(results, columns, row);

    Warning_data warning(atoi((*processed_row)[1].c_str()),
                         (*processed_row)[2],
                         this->get_message_type_from_severity((*processed_row)[0]));
    this->report_message(warning);
    delete processed_row;
  }
  mysql_free_result(results);

  return 0;
}

int64 Mysql_query_runner::report_mysql_error()
{
  Message_data message(mysql_errno(m_connection), mysql_error(m_connection),
                       Message_type_error);
  return this->report_message(message);
}

int64 Mysql_query_runner::report_message(Message_data &message)
{
  vector<I_callable<int64, const Message_data&>*>::reverse_iterator it;
  for (it= m_message_callbacks.rbegin();
    it != m_message_callbacks.rend();
    it++)
  {
    int64 callback_result= (**it)(message);
    if (callback_result < 0)
    {
      return 0;
    }
    else if (callback_result != 0)
    {
      return callback_result;
    }
  }
  return message.get_code();
}

enum Message_type Mysql_query_runner::get_message_type_from_severity(
  string severity)
{
  for (int i= 0; i+1 < Message_data::message_type_strings_count; i++)
  {
    String severity_string;
    uint dummy_errors;
    severity_string.copy(Message_data::message_type_strings[i],
      strlen(Message_data::message_type_strings[i]),
      &my_charset_latin1, m_connection->charset, &dummy_errors);

    if (my_strcasecmp(m_connection->charset, severity.c_str(),
      severity_string.c_ptr_safe()) == 0)
    {
      return (Message_type)i;
    }
  }
  return Message_type_unknown;
}

Mysql_query_runner::Store_result_helper::Store_result_helper(
  std::vector<const Row*>* result)
  : m_result(result)
{}

I_callable<int64, const Mysql_query_runner::Row&>*
  Mysql_query_runner::Store_result_helper::get_result_callback()
{
  return new Instance_callback<
    int64, const Row&, Store_result_helper>(
      this, &Store_result_helper::result_callback);
}

int64 Mysql_query_runner::Store_result_helper::result_callback(const Row& row)
{
  m_result->push_back(&row);
  return 0;
}

void Mysql_query_runner::cleanup_result(const Mysql_query_runner::Row& result)
{
  delete &result;
}

std::string Mysql_query_runner::escape_string(const std::string& original)
{
  std::string res;

  this->append_escape_string(&res, original);

  return res;
}

void Mysql_query_runner::append_escape_string(
  std::string* destination_string, const std::string& original)
{
  this->append_escape_string(
    destination_string, original.c_str(), original.size());
}

void Mysql_query_runner::append_escape_string(
  std::string* destination_string, const char* original, size_t original_length)
{
  size_t start_lenght= destination_string->size();
  size_t required_capacity= start_lenght + original_length * 2 + 1;
  destination_string->resize(required_capacity);

  int length = mysql_real_escape_string_quote(
    m_connection, &((*destination_string)[0]) + start_lenght, original,
    (ulong)original_length, '"');
  destination_string->resize(start_lenght + length);
}

void Mysql_query_runner::append_hex_string(
  std::string* destination_string, const char* original, size_t original_length)
{
  size_t start_lenght= destination_string->size();
  size_t required_capacity= start_lenght + original_length * 2 + 1;
  destination_string->resize(required_capacity);

  int length = mysql_hex_string(
    &((*destination_string)[0]) + start_lenght, original,
    original_length);
  destination_string->resize(start_lenght + length);
}

void Mysql_query_runner::cleanup_result(
  std::vector<const Mysql_query_runner::Row*>* result)
{
  for (vector<const Mysql_query_runner::Row*>::const_iterator
    it= result->begin(); it != result->end(); it++)
  {
    delete *it;
  }
  result->clear();
}

Mysql_query_runner::Row::Row(MYSQL_RES* mysql_result_info, unsigned int column_count,
                             MYSQL_ROW row)
  : m_buffer(NULL),
  m_buffer_capacity(0),
  m_buffer_size(0),
  m_mysql_result_info(mysql_result_info)
{
  size_t total_length= 0;
  unsigned long* column_lengths= mysql_fetch_lengths(mysql_result_info);
  for (unsigned int column = 0; column < column_count; column++)
    total_length+= column_lengths[column] + 1;

  this->reserve(column_count, total_length);
  // first column always starts at 0 offset
  m_buffer_starts.push_back(0);
  for (unsigned int column = 0; column < column_count; column++)
  {
    this->push_back(row[column], column_lengths[column]);
  }
}

Mysql_query_runner::Row::~Row()
{
  if (m_buffer != NULL)
    free(m_buffer);
}

std::string Mysql_query_runner::Row::operator[] (std::size_t index) const
{
  std::size_t length;
  const char* buffer= this->get_buffer(index, length);
  return std::string(buffer, length);
}

void Mysql_query_runner::Row::push_back(char* buff, std::size_t length)
{
  if (buff != NULL)
  {
    // Prepare buffer to be able to contain new data.
    this->reserve(
      m_buffer_starts.size(), m_buffer_size + length + 1);
    // Copy data.
    memcpy(&m_buffer[m_buffer_size], buff, length);
    // Set new buffer length.
    m_buffer_size += length + 1;
    // Set sentinel NULL terminating character.
    m_buffer[m_buffer_size - 1]= 0;
    // Add new end marker.
    m_buffer_starts.push_back(m_buffer_size);
  }
  else
  {
    // Prepare to be able to contain new data NULL value marker.
    this->reserve(m_buffer_starts.size(), m_buffer_size);
    // Add new end marker specifying NULL value.
    m_buffer_starts.push_back(SIZE_T_MAX);
  }
}

const char* Mysql_query_runner::Row::get_buffer(
  std::size_t index, std::size_t& length) const
{
  std::size_t start= SIZE_T_MAX;
  for (std::size_t start_index= index; start == SIZE_T_MAX; start_index--)
  {
    start= m_buffer_starts[start_index];
  }

  std::size_t end= m_buffer_starts[index + 1];
  length = (end - start - 1);
  return &m_buffer[start];
}

std::size_t Mysql_query_runner::Row::size_of_element(std::size_t index) const
{
  std::size_t res= 0;
  if (!is_value_null(index))
    this->get_buffer(index, res);
  return res;
}

bool Mysql_query_runner::Row::is_value_null(std::size_t index) const
{
  return m_buffer_starts[index + 1] == SIZE_T_MAX;
}

std::size_t Mysql_query_runner::Row::size() const
{
  return m_buffer_starts.size() - 1;
}

void Mysql_query_runner::Row::reserve(
  std::size_t strings, std::size_t buffer_size)
{
  if (strings >= m_buffer_starts.capacity())
  {
    m_buffer_starts.reserve(strings + 1);
  }
  if (buffer_size > m_buffer_capacity)
  {
    m_buffer_capacity= buffer_size;
    m_buffer= (char*)realloc(m_buffer, m_buffer_capacity);
  }
}

Mysql_query_runner::Row::Iterator Mysql_query_runner::Row::begin() const
{
  return Mysql_query_runner::Row::Iterator(*this, 0);
}

Mysql_query_runner::Row::Iterator Mysql_query_runner::Row::end() const
{
  return Mysql_query_runner::Row::Iterator(*this, m_buffer_starts.size() - 1);
}

MYSQL_RES* Mysql_query_runner::Row::get_mysql_result_info() const
{
  return m_mysql_result_info;
}

Mysql_query_runner::Row::Iterator::Iterator(const Row& row, std::size_t index)
  : m_row(row),
  m_index(index)
{}

bool Mysql_query_runner::Row::Iterator::is_value_null()
{
  return m_row.is_value_null(m_index);
}

std::string Mysql_query_runner::Row::Iterator::operator *()
{
  return m_row[m_index];
}

void Mysql_query_runner::Row::Iterator::operator ++()
{
  m_index++;
}

bool Mysql_query_runner::Row::Iterator::operator ==(const Iterator& other)
{
  return &m_row == &other.m_row && m_index == other.m_index;
}

bool Mysql_query_runner::Row::Iterator::operator !=(const Iterator& other)
{
  return !(*this == other);
}


Non-vitamin K oral anticoagulant use after cardiac surgery is rapidly increasing.
The prevalence of non-vitamin K oral anticoagulant use after cardiac surgery is unknown, particularly in patients with bioprosthetic valves. We sought to define the contemporary use and short-term safety of non-vitamin K oral anticoagulants after cardiac surgery. All patients undergoing bioprosthetic aortic valve replacement, bioprosthetic mitral valve replacement, or isolated coronary artery bypass grafting (2011-2018) were evaluated from a multicenter, regional Society of Thoracic Surgeons database. Patients were stratified by anticoagulant type (non-vitamin K oral anticoagulant vs vitamin K antagonist) and era (early [2011-2014] vs contemporary [2015-2018]). Of 34,188 patients, 18% (6063) were discharged on anticoagulation, of whom 23% were prescribed non-vitamin K oral anticoagulants. Among those receiving anticoagulation, non-vitamin K oral anticoagulant use has significantly increased from 10.3% to 35.4% in contemporary practice (P < .01). This trend was observed for each operation type (coronary artery bypass grafting 0.86%/year, bioprosthetic aortic valve replacement: 2.15%/year, bioprosthetic mitral valve replacement: 2.72%/year, all P < .01). In patients with postoperative atrial fibrillation receiving anticoagulation, non-vitamin K oral anticoagulant use has increased from 6.3% to 35.4% and 12.3% to 40.3% after bioprosthetic valve replacement and isolated coronary artery bypass grafting, respectively (both P < .01). In patients receiving anticoagulation at discharge, adjusted 30-day mortality (odds ratio, 1.94; P = .12) and reoperation (odds ratio, 0.79; P = .34) rates were not associated with anticoagulant choice, whereas non-vitamin K oral anticoagulant use was associated with an adjusted 0.9-day decrease (P < .01) in postoperative length of stay. Non-vitamin K oral anticoagulant use after cardiac surgery has dramatically increased since 2011. This trend is consistent regardless of indication for anticoagulation including bioprosthetic valves. Short-term outcomes support their safety in the cardiac surgery setting with shorter postoperative hospital stays. Long-term studies on the efficacy of non-vitamin K oral anticoagulants after cardiac surgery are still necessary.


/* Flot plugin for drawing all elements of a plot on the canvas.

Copyright (c) 2007-2013 IOLA and Ole Laursen.
Licensed under the MIT license.

Flot normally produces certain elements, like axis labels and the legend, using
HTML elements. This permits greater interactivity and customization, and often
looks better, due to cross-browser canvas text inconsistencies and limitations.

It can also be desirable to render the plot entirely in canvas, particularly
if the goal is to save it as an image, or if Flot is being used in a context
where the HTML DOM does not exist, as is the case within Node.js. This plugin
switches out Flot's standard drawing operations for canvas-only replacements.

Currently the plugin supports only axis labels, but it will eventually allow
every element of the plot to be rendered directly to canvas.

The plugin supports these options:

{
    canvas: boolean
}

The "canvas" option controls whether full canvas drawing is enabled, making it
possible to toggle on and off. This is useful when a plot uses HTML text in the
browser, but needs to redraw with canvas text when exporting as an image.

*/

(function($) {

	var options = {
		canvas: true
	};

	var render, getTextInfo, addText;

	// Cache the prototype hasOwnProperty for faster access

	var hasOwnProperty = Object.prototype.hasOwnProperty;

	function init(plot, classes) {

		var Canvas = classes.Canvas;

		// We only want to replace the functions once; the second time around
		// we would just get our new function back.  This whole replacing of
		// prototype functions is a disaster, and needs to be changed ASAP.

		if (render == null) {
			getTextInfo = Canvas.prototype.getTextInfo,
			addText = Canvas.prototype.addText,
			render = Canvas.prototype.render;
		}

		// Finishes rendering the canvas, including overlaid text

		Canvas.prototype.render = function() {

			if (!plot.getOptions().canvas) {
				return render.call(this);
			}

			var context = this.context,
				cache = this._textCache;

			// For each text layer, render elements marked as active

			context.save();
			context.textBaseline = "middle";

			for (var layerKey in cache) {
				if (hasOwnProperty.call(cache, layerKey)) {
					var layerCache = cache[layerKey];
					for (var styleKey in layerCache) {
						if (hasOwnProperty.call(layerCache, styleKey)) {
							var styleCache = layerCache[styleKey],
								updateStyles = true;
							for (var key in styleCache) {
								if (hasOwnProperty.call(styleCache, key)) {

									var info = styleCache[key],
										positions = info.positions,
										lines = info.lines;

									// Since every element at this level of the cache have the
									// same font and fill styles, we can just change them once
									// using the values from the first element.

									if (updateStyles) {
										context.fillStyle = info.font.color;
										context.font = info.font.definition;
										updateStyles = false;
									}

									for (var i = 0, position; position = positions[i]; i++) {
										if (position.active) {
											for (var j = 0, line; line = position.lines[j]; j++) {
												context.fillText(lines[j].text, line[0], line[1]);
											}
										} else {
											positions.splice(i--, 1);
										}
									}

									if (positions.length == 0) {
										delete styleCache[key];
									}
								}
							}
						}
					}
				}
			}

			context.restore();
		};

		// Creates (if necessary) and returns a text info object.
		//
		// When the canvas option is set, the object looks like this:
		//
		// {
		//     width: Width of the text's bounding box.
		//     height: Height of the text's bounding box.
		//     positions: Array of positions at which this text is drawn.
		//     lines: [{
		//         height: Height of this line.
		//         widths: Width of this line.
		//         text: Text on this line.
		//     }],
		//     font: {
		//         definition: Canvas font property string.
		//         color: Color of the text.
		//     },
		// }
		//
		// The positions array contains objects that look like this:
		//
		// {
		//     active: Flag indicating whether the text should be visible.
		//     lines: Array of [x, y] coordinates at which to draw the line.
		//     x: X coordinate at which to draw the text.
		//     y: Y coordinate at which to draw the text.
		// }

		Canvas.prototype.getTextInfo = function(layer, text, font, angle, width) {

			if (!plot.getOptions().canvas) {
				return getTextInfo.call(this, layer, text, font, angle, width);
			}

			var textStyle, layerCache, styleCache, info;

			// Cast the value to a string, in case we were given a number

			text = "" + text;

			// If the font is a font-spec object, generate a CSS definition

			if (typeof font === "object") {
				textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px " + font.family;
			} else {
				textStyle = font;
			}

			// Retrieve (or create) the cache for the text's layer and styles

			layerCache = this._textCache[layer];

			if (layerCache == null) {
				layerCache = this._textCache[layer] = {};
			}

			styleCache = layerCache[textStyle];

			if (styleCache == null) {
				styleCache = layerCache[textStyle] = {};
			}

			info = styleCache[text];

			if (info == null) {

				var context = this.context;

				// If the font was provided as CSS, create a div with those
				// classes and examine it to generate a canvas font spec.

				if (typeof font !== "object") {

					var element = $("<div> </div>")
						.css("position", "absolute")
						.addClass(typeof font === "string" ? font : null)
						.appendTo(this.getTextLayer(layer));

					font = {
						lineHeight: element.height(),
						style: element.css("font-style"),
						variant: element.css("font-variant"),
						weight: element.css("font-weight"),
						family: element.css("font-family"),
						color: element.css("color")
					};

					// Setting line-height to 1, without units, sets it equal
					// to the font-size, even if the font-size is abstract,
					// like 'smaller'.  This enables us to read the real size
					// via the element's height, working around browsers that
					// return the literal 'smaller' value.

					font.size = element.css("line-height", 1).height();

					element.remove();
				}

				textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px " + font.family;

				// Create a new info object, initializing the dimensions to
				// zero so we can count them up line-by-line.

				info = styleCache[text] = {
					width: 0,
					height: 0,
					positions: [],
					lines: [],
					font: {
						definition: textStyle,
						color: font.color
					}
				};

				context.save();
				context.font = textStyle;

				// Canvas can't handle multi-line strings; break on various
				// newlines, including HTML brs, to build a list of lines.
				// Note that we could split directly on regexps, but IE < 9 is
				// broken; revisit when we drop IE 7/8 support.

				var lines = (text + "").replace(/<br ?\/?>|\r\n|\r/g, "\n").split("\n");

				for (var i = 0; i < lines.length; ++i) {

					var lineText = lines[i],
						measured = context.measureText(lineText);

					info.width = Math.max(measured.width, info.width);
					info.height += font.lineHeight;

					info.lines.push({
						text: lineText,
						width: measured.width,
						height: font.lineHeight
					});
				}

				context.restore();
			}

			return info;
		};

		// Adds a text string to the canvas text overlay.

		Canvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) {

			if (!plot.getOptions().canvas) {
				return addText.call(this, layer, x, y, text, font, angle, width, halign, valign);
			}

			var info = this.getTextInfo(layer, text, font, angle, width),
				positions = info.positions,
				lines = info.lines;

			// Text is drawn with baseline 'middle', which we need to account
			// for by adding half a line's height to the y position.

			y += info.height / lines.length / 2;

			// Tweak the initial y-position to match vertical alignment

			if (valign == "middle") {
				y = Math.round(y - info.height / 2);
			} else if (valign == "bottom") {
				y = Math.round(y - info.height);
			} else {
				y = Math.round(y);
			}

			// FIXME: LEGACY BROWSER FIX
			// AFFECTS: Opera < 12.00

			// Offset the y coordinate, since Opera is off pretty
			// consistently compared to the other browsers.

			if (!!(window.opera && window.opera.version().split(".")[0] < 12)) {
				y -= 2;
			}

			// Determine whether this text already exists at this position.
			// If so, mark it for inclusion in the next render pass.

			for (var i = 0, position; position = positions[i]; i++) {
				if (position.x == x && position.y == y) {
					position.active = true;
					return;
				}
			}

			// If the text doesn't exist at this position, create a new entry

			position = {
				active: true,
				lines: [],
				x: x,
				y: y
			};

			positions.push(position);

			// Fill in the x & y positions of each line, adjusting them
			// individually for horizontal alignment.

			for (var i = 0, line; line = lines[i]; i++) {
				if (halign == "center") {
					position.lines.push([Math.round(x - line.width / 2), y]);
				} else if (halign == "right") {
					position.lines.push([Math.round(x - line.width), y]);
				} else {
					position.lines.push([Math.round(x), y]);
				}
				y += line.height;
			}
		};
	}

	$.plot.plugins.push({
		init: init,
		options: options,
		name: "canvas",
		version: "1.0"
	});

})(jQuery);